delphi - 成功运行后 Delphi 中的访问冲突

标签 delphi

我在 Delphi 中编写了一个程序来计算、显示和保存用户定义的行数的帕斯卡三角形。它工作正常(显示三角形,并允许我保存它),除了它最后出现访问冲突!这是消息:

模块“Project1.exe”中地址 004031DB 的访问冲突。读取地址 00000000。

我在过程中有一个二维动态数组,但我在最后释放了内存(:= 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;

最佳答案

Read of address 00000000

这表明您正在尝试使用 nil 指针访问内存。要知道为什么会这样,需要代码。目前只有你有代码,所以只有你能解释。

在调试器中运行程序。如果 RTL/VCL 代码中出现错误,请启用调试 DCU。确保调试器配置为中断异常。运行您的程序并触发错误。调试器将显示正在取消引用的 nil 对象。然后你必须弄清楚为什么那个引用是零。

您添加到答案中的代码有缓冲区溢出,这肯定可以解释问题。您的 SetLength 不正确,应为:
SetLength(PT, K, N*2);

您的代码越界写入内存,从而破坏了堆。您应该要求编译器对您的数组边界进行运行时检查。启用编译器的范围检查选项。如果你这样做了,你自己就会发现这个错误。

值得你不需要 try/finally block ,因为编译器会自动插入一个隐藏 block 。一个就够了,就不需要两个了。动态数组是一种托管类型,其内存在变量离开作用域时被释放。

关于delphi - 成功运行后 Delphi 中的访问冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18599729/

相关文章:

delphi - 是否有混合列表框和 TreeView 的 C++Builder 组件?

delphi - 为什么 COMMON_APPDATA 在 Windows XP 上返回为空字符串

delphi - 如何在接口(interface)中实现参数化方法以在 Spring 框架中使用

delphi - 更改驱动器分区中所有文件的属性

sockets - WinSock:服务器未按客户端发送的相同顺序接收数据

json - 为什么 TJson.ObjectToJsonObject/ObjectToJsonString 将记录字段表示为 JSON 数组?

javascript - 无法从 JavaScript 调用 Delphi ActiveX 方法

delphi - 如何在delphi中找到两个开始和结束字符串之间的字符串?

c++ - 代码从 C/C++ 转换为 Delphi

delphi - 向 TActionList 中的 Action 添加新属性