我似乎无法想出这个。我的程序编译并成功运行,但在调试期间,只有在关闭程序时会弹出一个消息框,显示“无效的指针操作”。我已经仔细检查了所有FormCloseQuery和FormDestory事件是否存在任何语法或逻辑错误。我发现没有,他们按预期执行没有任何错误。
当我告诉编译器在无效指针操作错误时中断时,除了挂起程序之外它什么都不做。此时,我不得不终止或终止该过程。
你怎么知道这个?
提前致谢,
答案 0 :(得分:27)
内存管理器在尝试释放无效内存时抛出无效指针异常。有三种方法可以实现。
最常见的是因为你试图释放你已经释放的对象。如果打开FastMM的FullDebugMode,它将检测到这一点并直接指出问题所在。 (但请确保构建一个映射文件,以便它具有创建有用堆栈跟踪所需的信息。)
第二种方法是,如果你试图释放分配给内存管理器以外某处的内存。将Delphi EXE中的字符串传递给没有使用共享内存管理器功能的Delphi DLL时,我已经看过几次了。
第三种方式涉及直接搞乱指针,可能不适用于你。如果您尝试FreeMem
或Dispose
一个不指向FastMM分配的实际内存块的错误指针,您将收到此错误。
这很可能是第一个。使用FullDebugMode,您可以轻松找到问题的根源。
答案 1 :(得分:10)
当您告诉Delphi内存管理器释放不属于它的内存时,会发生无效的指针操作。有三种方式可能发生:
FreeMem
释放某些其他内存管理员分配的内容(例如GlobalAlloc
或CoTaskMemAlloc
)。在你的程序的某个地方,你正在做其中的一件事。调试器已检测到内存管理器抛出的异常,因此请进行一些调试。从堆栈跟踪中,您应该能够看到您尝试释放的变量。检查程序的其余部分,了解使用变量的其他方法。
MadExcept和Eureka Log等工具可以帮助您找到双重免费错误。他们可以跟踪有问题的指针在哪里被分配以及第一次被释放的位置,这有时是足够的信息来找出你的错误并停止多次释放。
答案 2 :(得分:1)
可能发生无效指针操作的第四个原因。我有两个指针,其中数组[0..1000]是真实的,第三个指针是真实的数组[1..200]。所有3个指针在哪里初始化 对于i:= 0到1000做 开始 PTR1 ^ [I]:= 0; ptr2所^ [I]:= 0; PTR3 ^ [I]:= 0; 结束; 虽然这个糟糕的编程并没有打扰Delphi中的Pascal,但是调用Dispose中的任何一个指针都会导致无效的指针操作。修复只是正确初始化第三个指针。
答案 3 :(得分:0)
在Delphi调试过程中,我被这种“指示错误”所困扰。
检查是否有任何启用了“允许函数调用”的监视变量,或者尝试在同一单元(或全局)中显示可能未初始化的其他变量的监视。当在断点处停止时,这可能导致Delphi的调试器尝试通过访问未初始化的指针或变量的函数调用来显示该值。导致AV的实际变量甚至不在您的监视列表中。