【问题标题】:Access violations on string operations in DelphiDelphi中字符串操作的访问冲突
【发布时间】:2013-09-20 11:14:01
【问题描述】:

我有一个 Delphi 应用程序,它从文件中读取数据并将其存储在数组中。文件中的每一行都包含一个地址、lineTypeIndicator 和数据。这是算法(包含我认为很关键的代码):

AssignFile(inputFile, inFileName);
Reset(inputFile);
  while not EOF(inputFile) do
  begin
    Readln(inputFile,fileLineBuffer);        
     if  Copy(fileLineBuffer, 8, 2) = '01' then  //Never managed to catch the error here
    begin
      break;
    end;

    //extract the address from the line and use it to determine max and min address.
  end;

//Now that you have min and max address, use it to set the length of an char array
SetLength(memoryArray,(lastAddress - firstAddress) * 2);

Reset(inputFile);
  while not EOF(inputFile) do
  begin
    Readln(inputFile,fileLineBuffer);

     if  Copy(fileLineBuffer, 8, 2) = '01' then    //I caught all the errors here
    begin
      break;
    end;

    //extract the address and data from the fileLineBuffer and place it in the corresponding place in an array
  end;

每次用户单击表单上的相应按钮时都会执行此代码。它在执行的前几次运行,但在几次运行后我得到了这个:

MyProgram.exe 出现错误消息:'在 0x00406111 处的访问冲突: 写入地址 0x00090d1c(这会有所不同)。进程停止。使用步骤 或运行以继续。

对我来说,这闻起来像是某种堆溢出。我试过替换

if  Copy(fileLineBuffer, 8, 2) = '01' then              

lineTypeBuffer :=   Copy(fileLineBuffer, 8, 2);
if  lineTypeBuffer = '01' then                   

if  (fileLineBuffer[8] = '0') and (fileLineBuffer[9] = '1') then 

但它没有帮助。 关于我应该如何解决这个问题的任何建议?

附:尝试在 Win7 32 位和 Win7 64 位上运行它 - 没有区别 附言抱歉这个问题太长了。

【问题讨论】:

    标签: windows delphi delphi-7 access-violation


    【解决方案1】:

    的唯一解释
    Copy(fileLineBuffer, 8, 2) = '01'
    

    导致访问冲突的原因是您损坏了堆。

    您程序中的其他内容正在写入越界并破坏堆。此类问题可能难以诊断,因为故障通常在代码的一部分中,但错误发生在其他地方。某些代码损坏了堆,然后由于之前的堆损坏,后续的堆操作失败。

    我对自己的诊断很有信心,因为已知 Delphi 字符串变量可以工作,Copy 可以工作,并且字符串相等性测试可以工作。换句话说,发生错误的代码行中没有错误。因此错误在别处。

    一些可能有帮助的调试工具:

    • FastMM 处于完全调试模式。
    • 范围检查(通过项目的编译器选项启用)。

    【讨论】:

    • 谢谢,这是正确的。但是,我不确定如何将答案标记为选中。 '将它放在数组中的相应位置'存在问题。对应的地方正好出界。由于我是 Delphi 的新手,我希望在写入发生后我会​​立即收到异常。但是写入成功并损坏了堆。我可以将其整合到您的答案中,我认为这对未来的读者会更有用,因此我可以将其标记为正确。或者我可以自己写一个答案。我更喜欢第一个选项,因为你是对的,你应该得到信用:D
    • 你可以接受我的回答。这句话您的程序中的其他内容正在超出范围并损坏堆 是您要我添加的内容。它已经在那里了。启用范围检查将引导您找到特定问题的解决方案。我没有必要添加您的问题的细节,或者您这样做,因为它们不在问题中。我的回答是笼统的。第 1 步,您描述的症状只能用堆损坏来解释。堆损坏发生在其他地方。第 2 步,使用调试工具定位其他点。
    • 无论如何,我已经添加了一些段落,提供了有关堆损坏的更多信息。我希望这可以改善答案。
    • 顺便问一下,您打开范围检查并立即发现错误,我是否正确?该程序的范围检查功能异常强大。我总是对默认情况下未启用它感到惊讶。
    • 不幸的是,范围检查对我仍然不起作用。我在项目选项中打开了它,但我仍然在同一行中收到错误(在堆损坏之后)。我希望它会在我尝试写越界时立即通知我。我对吗?我识别错误的方法是简单地检查所有基于索引的写入几次:D 我是如此专注于“复制”行,以至于我忽略了其他所有内容 - 直到你指出我正确的方向。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多