在将一些数据输入到动态多维数组后关闭我的应用程序时继续获取AV

Sil*_*ior 2 delphi multidimensional-array dynamic-arrays delphi-xe3

我在其中一个项目中遇到了一些奇怪的问题.最奇怪的是,这只发生在这个项目中,我无法在另一个项目中重新创建它.

Luckilly这是一个很小的项目(旨在为SO提供一个问题的答案 - 仍然没有完成)所以我设法弄清楚它必须做什么来破坏我在设计上放置在我的表单上的TImage组件时间并在设计时也为其设置BMP图像.

我得到的AV是:项目Project1.exe引发异常类$ C0000005,消息'访问冲突在0x00407430:读取地址0xfffffffc'.

最后三个调用堆栈是:
Vcl.Graphics.TBitmapCanvas.Destroy
Vcl.Graphics.TCanvasDestroy
System.TObject.Free

此外,Delphi将我置于"Destroy"行的TObbject.Free方法中的System.pas单元中.

procedure TObject.Free;
begin
  if Self <> nil then
{$IFDEF AUTOREFCOUNT}
    __ObjRelease;
{$ELSE}
    Destroy;
{$ENDIF}
end;
Run Code Online (Sandbox Code Playgroud)

此时Self的值仅显示为().

但是为什么只有在我将一些数据存储到我的多维数组中时才会发生这种AV.
我可以在运行时创建和设置多维数组的大小,每一个都很好.但是一旦我更改了这个多维数组中某些项的数据,我就会在关闭应用程序时获得AV.

这是我的完整源代码:

unit Unit2;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.ExtCtrls;

type
  TSubImage = record
    LeftBound: Integer;
    RightBound: Integer;
    TopBound: Integer;
    BottomBound: Integer;
  end;

  TForm2 = class(TForm)
    Button1: TButton;
    ListBox1: TListBox;
    Image1: TImage;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form2: TForm2;
  SubImages: Array of TSubImage;

implementation

{$R *.dfm}

procedure TForm2.Button1Click(Sender: TObject);
var X,Y,I: Integer;
    RegionMask: Array of Array of Integer;
begin
  SetLength(RegionMask,Image1.Width+1,Image1.Height+1);
  for Y := 0 to Image1.Height do
  begin
    for X := 0 to Image1.Width do
    begin
      if Image1.Canvas.Pixels[X,Y] <> clFuchsia then
      begin
        //Check left pixel
        if X > 0 then
        begin
          if RegionMask[X-1,Y] <> 0 then
          begin
            RegionMask[X,Y] := RegionMask[X-1,Y];
            //Check to se if pixel X position is leftwards to subimages left bound
            if Subimages[RegionMask[X,Y]].LeftBound > X then
              //Move subimage left bound to match pixel X position
              Subimages[RegionMask[X,Y]].LeftBound := X;
            //Check to se if pixel X position is rightwards to subimages right bound
            if Subimages[RegionMask[X,Y]].RightBound < X then
              //Move subimage right bound to match pixel X position
              Subimages[RegionMask[X,Y]].RightBound := X;
            //Check to se if pixel Y position is upwards to subimages top bound
            if Subimages[RegionMask[X,Y]].TopBound > Y then
              //Move subimage top bound to match pixel Y position
              Subimages[RegionMask[X,Y]].TopBound := Y;
            //Check to se if pixel Y position is downwards to subimages bottom bound
            if Subimages[RegionMask[X,Y]].BottomBound < Y then
              //Move subimage bottom bound to match pixel Y position
              Subimages[RegionMask[X,Y]].BottomBound := Y;
          end;
        end;
        //Check top pixel
        if Y > 0 then
        begin
          if RegionMask[X,Y-1] <> 0 then
          begin
            RegionMask[X,Y] := RegionMask[X,Y-1];
            //Check to se if pixel X position is leftwards to subimages left bound
            if Subimages[RegionMask[X,Y]].LeftBound > X then
              //Move subimage left bound to match pixel X position
              Subimages[RegionMask[X,Y]].LeftBound := X;
            //Check to se if pixel X position is rightwards to subimages right bound
            if Subimages[RegionMask[X,Y]].RightBound < X then
              //Move subimage right bound to match pixel X position
              Subimages[RegionMask[X,Y]].RightBound := X;
            //Check to se if pixel Y position is upwards to subimages top bound
            if Subimages[RegionMask[X,Y]].TopBound > Y then
              //Move subimage top bound to match pixel Y position
              Subimages[RegionMask[X,Y]].TopBound := Y;
            //Check to se if pixel Y position is downwards to subimages bottom bound
            if Subimages[RegionMask[X,Y]].BottomBound < Y then
              //Move subimage bottom bound to match pixel Y position
              Subimages[RegionMask[X,Y]].BottomBound := Y;
          end;
        end;
        //Create new region
        if RegionMask[X,Y] = 0 then
        begin
          SetLength(SubImages,Length(SubImages)+1);

          //If I comment out this line no exception is raised on closing the from
          RegionMask[X,Y] := Length(SubImages);

          //Set subimage initial bounds which are coordinates of one pixel
          //since we created new region for this pixel
          SubImages[RegionMask[X,Y]].LeftBound := X;
          SubImages[RegionMask[X,Y]].RightBound := X;
          SubImages[RegionMask[X,Y]].TopBound := Y;
          SubImages[RegionMask[X,Y]].BottomBound := Y;
        end;
      end;
    end;
  end;
  Form2.Caption := IntToStr(Length(SubImages)-1);
  for I := 0 to Length(Subimages)-1 do
  begin
    ListBox1.Items.Add(IntToStr(SubImages[I].LeftBound)+','+
                       IntToStr(SubImages[I].RightBound)+','+
                       IntToStr(SubImages[I].TopBound)+','+
                       IntToStr(SubImages[I].BottomBound));
  end;
  SetLength(RegionMask,0,0);
  RegionMask := nil;
end;

end.
Run Code Online (Sandbox Code Playgroud)

Dav*_*ois 5

你在这些行中有一次性错误.考虑第一次向SubImages添加元素.SubImages的长度为1,但数组中唯一的元素是SubImages [0].将RegionMask [X,Y]设置为1,然后使用该值索引数组.所以你试图访问超出数组末尾的一个项目.

   SetLength(SubImages,Length(SubImages)+1);

      RegionMask[X,Y] := Length(SubImages);

      SubImages[RegionMask[X,Y]].LeftBound := X;
Run Code Online (Sandbox Code Playgroud)

  • 一旦开始将内存更改超出范围,就可以影响存储在内存中的任何内容.内存中的数组在哪里?什么超越它? (3认同)