【问题标题】:Delphi access violation assigning local variableDelphi访问冲突分配局部变量
【发布时间】:2010-04-27 17:03:01
【问题描述】:

这似乎是世界上最简单的事情,我已经准备好把头发拉出来了。

我有一个看起来像这样的单元;

Unit  myUnit;
// ...
//normal declarations
//...
Public
//bunch of procedures including
Procedure myProcedure;

const
//bunch of constants

var
//bunch of vars including
myCounter:integer;

Implementation
Uses //(all my uses)

// All of my procedures including

Procedure myProcedure;
   try
     // load items from file to TListBox - this all works
   except
   on EReadError do begin
     // handle exception
     end;
   end; //try



   myCounter:=0;  //  <--  ACCESS VIOLATION HERE
   while myCounter //...etc

这是一个简单的变量赋值,我不知道它为什么这样做。我已经尝试将变量声明为单元的本地变量、过程的全局变量——无论我在哪里尝试这样做,我都无法将零值赋给在此过程中任何地方声明的整数,而不会引发访问违反。我完全被难住了。

我从同一单元内的按钮 OnClick 处理程序内部调用该过程,但无论我从何处调用它都会引发异常。疯狂的是,我在整个程序的其他十几个地方做同样的事情,没有任何问题。为什么在这里?我完全不知所措。

【问题讨论】:

  • 您能否提供访问冲突错误消息的确切文本,包括地址?这可能很重要。
  • ---------------------------- 调试器异常通知 ------------ --------------- 项目 .exe 引发异常类 EAccessViolation,并带有消息“模块 '.exe 中地址 0043FDE8 的访问冲突” .读取地址 00000008'。 --------------------------------------- 中断继续帮助 -------------------- --------

标签: delphi variables access-violation


【解决方案1】:

Read of address 00000008 表示您正在从 nil 指针读取偏移 8 个字节的变量。这根本不适合你在这里尝试做的事情,因为你是在写,而不是在读,你写的是一个常量,而不是从某个地方读取的变量。

您确定这是触发异常的实际行吗?你有没有在这条线上设置断点?您是否尝试过将此行移到程序的顶部?

如果没有您面前的实际代码,很难确定,但如果我不得不猜测,我会说 before 这行导致异常,然后是指令指针已经增加,所以 Delphi 突出显示下一行。

【讨论】:

  • 好点。硬件异常通常发生在指令点移动到下一条指令/语句之后。看看后视镜,看看你跑过什么。 ;>
  • 我刚刚在进行 CPU 跟踪后发现了这一点,但你是对的 - 我正在清除(使用 xx.Clear 方法)导致问题的 TIdEmailAddressList(Indy 组件)。杂耍事物并稍后访问它也会引发异常。 **edit - 实际上,正在清除的是 TListBox。一样,问题解决了。感谢大家的好主意。过早秃顶将不得不等待另一天。干杯。
【解决方案2】:

我不认为你的错误意味着任何像它看起来的那样。当您从这样的一段代码中获得访问冲突时,它没有正常的方式产生访问冲突,您正在以某种方式查看被破坏的内存。

在 CPU 窗口中逐步检查有问题的代码,看看到底发生了什么。

【讨论】:

  • 公平点。细齿梳子总是最后的手段,我希望我做了一些明显错误的事情,这可能是显而易见的。我会试一试,如果不出意外,我想我只会建造一个新单元,而不是添加到旧单元中。不能说我渴望花费更多的时间,而不是已经浪费在通过 CPU 寄存器跟踪解决 helloWorld 问题的时间。
  • 另一个选项:在最初计算变量的位置设置断点。验证是否存储了正确的数字,然后在指针上设置内存修改断点。 (请注意,我已经在操作系统本身中解决了这些问题。它可能非常丑陋。)
【解决方案3】:

您正在使用 with 语句并且正在查看不同的 myCounter?

您的代码的某些部分正在写入它不应该写入的内存,或者在不应该释放的情况下释放,并且在访问该特定局部变量时意外导致 AV 错误?

【讨论】:

  • 搞笑——有些人很快就责怪“与”,他们甚至指责它在甚至不涉及它的代码中造成问题。虽然我们应该小心……在这种情况下,也许 GOTO 语句是负责任的。 ;)
  • @Deltics - 由于 OP 并未显示所有内容,尽管有些牵强,但这与其他任何事情一样好。
  • @Lieven:根本不是真的。这个猜测不如 100% 准确的猜测(假设这个是 0% 准确)。 :)
  • @Deltics - 好吧,你说了算。 :)
【解决方案4】:

赋值 myCounter := 0 抛出访问冲突表明存储全局变量的数据段已从内存中删除,或者寄存器在您的 myProcedure 例程中被冲洗。

使用 CPU 视图查看用于访问全局变量的寄存器,然后从那里向后工作以查看该/那些寄存器出错的地方。

【讨论】:

    【解决方案5】:

    将 MyCounter 移到 var 列表的顶部,看看它是否仍然发生。如果问题消失了,请查看上面声明的变量 - 您可能会发现一些有趣的东西,例如超出其边界的数组。

    【讨论】:

    • 访问简单变量不会导致访问冲突。
    • 不,没有数组,移动 var 也无济于事。这是一个相当大且非常稳定的应用程序,在我添加这个小 sn-p 之前它运行良好。
    • @Loren - 谢谢,是的,你是对的。上周我帮助一位同事解决了似乎完全相同的问题,但现在我想起来了,数组正在覆盖一个指针,而不是一个简单的 var。有趣的是,这很酷,因为数组是在指针下方声明的,但是当数组声明为 [1..5] 时,他通过使用元素 [0] “下溢”了。哎呀!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多