我构建了一个减少像素宽度的应用程序。
当我按下该应用程序的按钮两到三次时,将显示消息并说堆栈溢出。
这里是留言:
我的申请上的错误行
这是我的代码:
procedure TForm1.cariThin();
var
baris_gbr, kolom_gbr, x, y, a, b, i, j, p1, p2, n : integer;
imgval : array [0..500,0..500] of integer;
mark : array [0..500,0..500] of integer;
nb : array [1..9] of integer;
hasdelete: boolean;
R, G, BL, AB : integer;
begin
Image3.Width := Image1.Width;
Image3.Height := Image1.Height;
baris_gbr := Image1.Picture.Height;
kolom_gbr := Image1.Picture.Width;
For kolom_gbr:= 0 To image1.Width - 1 Do
Begin
For baris_gbr:= 0 To image1.Height - 1 Do
Begin
R:= GetRValue(image1.Canvas.Pixels[kolom_gbr, baris_gbr]);
G:= GetGValue(image1.Canvas.Pixels[kolom_gbr, baris_gbr]);
BL:= GetBValue(image1.Canvas.Pixels[kolom_gbr, baris_gbr]);
AB:= (R + G + BL) Div 3;
if (AB > 200) then
begin
Image1.Canvas.Pixels[kolom_gbr, baris_gbr] := rgb(255,255,255);
end
else
begin
Image1.Canvas.Pixels[kolom_gbr, baris_gbr] := rgb(0,0,0);
end;
End;
End;
for y := 0 to baris_gbr-1 do
begin
for x := 0 to kolom_gbr-1 do
begin
if (Image1.canvas.pixels[x,y] = clBlack) then
begin
imgval[x,y] := 1;
end
else
begin
imgval[x,y] := 0;
end;
end;
end;
hasdelete := True;
while (hasdelete) do
begin
hasdelete := False;
for y := 0 to baris_gbr-1 do
begin
for x := 0 to kolom_gbr-1 do
begin
if (imgval[x,y] = 1) then
begin
for n:=1 to 8 do
begin
nb[n] := 0;
nb[1] := imgval[x,y];
nb[2] := imgval[x,y-1];
nb[3] := imgval[x+1,y-1];
nb[4] := imgval[x+1,y];
nb[5] := imgval[x+1,y+1];
nb[6] := imgval[x,y+1];
nb[7] := imgval[x-1,y+1];
nb[8] := imgval[x-1,y];
nb[9] := imgval[x-1,y-1];
a := 0;
end;
for i:= 2 to 8 do
begin
if ((nb[i] = 0) AND (nb[i+1] = 1)) then
begin
inc(a);
end;
end;
if ((nb[9] = 0) AND (nb[2] = 1)) then
begin
inc(a);
end;
b := nb[2] + nb[3] + nb[4] + nb[5] + nb[6] + nb[7] + nb[8] + nb[9];
p1 := nb[2] * nb[4] * nb[6];
p2 := nb[4] * nb[6] * nb[8];
if ((a = 1) AND ((b>=2) AND (b <= 6)) AND (p1 = 0) AND (p2 = 0)) then
begin
mark[x,y] := 0;
hasdelete := true;
end
else
begin
mark[x,y] := 1;
end
end
else
begin
mark[x,y] := 0;
end;
end;
end;
for y:=0 to baris_gbr-1 do
begin
for x:=0 to kolom_gbr-1 do
begin
imgval[x,y] := mark[x,y];
end;
end;
end;
end;
为什么我的应用程序会说溢出?有没有解决方案来解决它?或者我们可以异常处理程序吗?感谢
编辑
现在我的申请说违反了访问权限。
这引起了这一行的错误:nb [7]:= imgval [x-1,y + 1]; 为什么它确实发生了?
答案 0 :(得分:5)
var
imgval : array [0..500,0..500] of integer;
mark : array [0..500,0..500] of integer;
这些变量位于堆栈上并且非常庞大。它们的尺寸为501 * 501 * 4 = 1,004,004。默认堆栈大小为1MB。这些大型数组是堆栈溢出的原因。
您需要使用动态分配的数组。或者避免需要存储包含每个像素的信息的2D数组,而是以较小的子块处理图像。我不知道这是否可行,因为我不知道代码试图做什么。那是你锻炼的。
当然,使用动态分配的数组的一个优点是,您不需要像目前那样运行缓冲区溢出的手套。如果图像的任一维度超过501,则表示您已超出缓冲区。我希望您已在编译器选项中启用了范围检查。
for y := 0 to baris_gbr-1 do
和
for x := 0 to kolom_gbr-1 do
无法正确。 baris_gbr
和kolom_gbr
变量未初始化,因为它们最近被用作循环变量。因此,除了启用范围检查之外,您还需要打开提示和警告,然后注意它们。