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)
你在这些行中有一次性错误.考虑第一次向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)