我认为访问冲突通常是由于尝试访问尚未创建的内存中的某些内容,如对象等?
我发现很难确定什么触发访问冲突,然后在哪里进行所需的更改来尝试和停止/修复它们。
一个例子是我现在正在开展的个人项目。我在每个节点的TTreeView Node.Data属性中存储一些数据。节点可以被多个选择和导出(导出遍历每个选定的节点并将特定数据保存到文本文件中 – 保存到文本文件中的信息是存储在nodes.data中的信息)。文件也可以导入到Treeview(将文本文件的内容保存到node.data中)。
该示例中的问题是如果我将文件导入到Treeview中,然后导出它们,则它将完美运行。但是,如果我在运行时添加一个节点并导出它们,我得到:
“Access Violation at address 00405772 in module ‘Project1.exe’. Read of address 00000388.”
我对此的想法必须是我将数据分配给创建的节点的方式,也可能与导入时分配的方式不同,但是对我来说看起来都很好。访问冲突仅在导出时显示,导入文件不会发生。
我不是在寻找一个修复上面的例子,但主要是建议/提示如何查找和修复这种类型的错误。我经常不会获得访问冲突,但是当我做这些事情真的很难追踪和修复。
所以建议和提示将是非常有用的。
解决方法
使用调试器,如Delphi。它会告诉你AV发生了什么代码行。从那里通过查看callstack和局部变量等来弄清楚您的问题。有时,如果您使用Debug DCUs编译,也可以帮助您。
如果您没有调试器,因为它只发生在客户端,您可能需要使用MadExcept或JclDebug来使用callstack记录异常并将其发送给您。它给你更少的细节,但可能指向你正确的方向。
有些工具可能会通过更积极地检查来更早地找到这些问题。 FastMM内存管理器具有这样的选项。
编辑
“Access Violation at address 00405772
in module ‘Project1.exe’. Read of
address 00000388.”
因此,您的问题导致模块“Project1.exe”中的地址为00405772的AV。 Delphi调试器将带您到正确的代码行(或使用Find Error)。
它正在尝试在地址00000388读取内存。这是非常接近00000000(nil),所以这可能意味着访问一个数组或动态数组为零的指针/引用。如果它是一个字节数组,它将是项目388.或者它可以是一个相当大的对象或具有很多字段的记录的字段。对象或记录指针/引用将为零。