我在Delphi中编写了一个程序,用于计算,显示和保存用户定义行数的Pascals三角形。它工作正常(显示三角形,并允许我保存它),除了它最后出现访问冲突!以下是信息:
模块“Project1.exe”中地址004031DB的访问冲突。读取地址00000000.
我在程序中有一个2D动态数组但是我在最后释放了内存(:= nil)。为什么它仍然给我一个访问冲突?很沮丧!
我在档案馆搜索了一个答案但找不到合适的答案。任何帮助将不胜感激。
这是代码(我有点犹豫,因为有一些代码:
procedure TForm1.btnPTClick(Sender: TObject);
var
I, J, K, N, MidCol: integer;
PT: array of array of integer;
Row: string;
begin
K := StrToInt(lblNumRows.Text);
N := StrToInt(lblNumRows.Text);//# values in row = row number
try
//initiatlize the array
SetLength(PT, K, (N*2)-1);
for I := 0 to K-1 do
for J := 0 to (N*2-1) do
PT[I,J] := 0;
MidCol := (N*2 div 2)-1;//MidCol already 0-based
for I := 0 to K-1 do
begin
if (I = 0) then
PT[I,MidCol] := 1//first row gets 1 in the middle column
else if I = 1 then
begin
PT[I,MidCol-1] := 1;
PT[I,MidCol+1] := 1; //first and last value in second = 1
end
else //if any other row
begin
//Middle column
PT[I, MidCol] := PT[I-1,MidCol-1] + PT[I-1,MidCol+1];
//right triangle
for J := MidCol+1 to (N*2-1) do
begin
if (PT[I-1, J-1]=1) then//if already at the end of prev row
begin
PT[I,J] := 1;
break;
end
else
PT[I,J] := PT[I-1,J-1] + PT[I-1,J+1];
end;
//left triangle
for J := MidCol-1 downto 0 do
begin
if (PT[I-1, J+1] = 1) then //if already at the end of prev row
begin
PT[I,J] := 1;
break;
end
else
PT[I,J] := PT[I-1,J-1] + PT[I-1,J+1];
end;
end;
end;
//now add the pyramid to the memo
Application.ProcessMessages;
for I := 0 to K-1 do
begin
Row := '';
for J := 0 to N*2-1 do
begin
if (PT[I,J] = 0) then Row := Row + ' '
else Row := Row + IntToStr(PT[I,J]);
end;
Memo.Lines.Add(Row);
end;
finally
SetLength(PT, 0, 0);
end;
end;
答案 0 :(得分:8)
Read of address 00000000
这表示您尝试使用nil指针访问内存。要知道为什么会这样,需要代码。目前只有你有代码,所以只有你可以解释。
在调试器中运行程序。如果在RTL / VCL代码中引发错误,则启用调试DCU。确保将调试器配置为中断异常。运行程序并触发错误。调试器将显示哪个nil对象正在被引用。然后你必须弄清楚为什么这个参考是零。
您添加到答案中的代码有缓冲区溢出,这当然可以解释问题。你的SetLength不正确,应该是:
SetLength(PT, K, N*2);
您的代码写入内存越界,因此破坏了堆。您应该要求编译器对数组边界进行运行时检查。启用编译器的范围检查选项。如果你这样做了,你自己就会发现这个错误。
因为编译器会自动插入一个隐藏块,所以不需要try / finally块。当一个人满足时,不需要两个。动态数组是托管类型,当变量离开范围时,其内存将被释放。
答案 1 :(得分:1)
按F7,在调试器中启动项目。
在主菜单中查找“查找错误...”选项(在Delphi 7中,它位于“搜索”菜单下)
然后输入例外地址:004031DB。
这将显示发生异常的确切行。
Read of address 00000000
通常表示您正在使用具有零值的指针。