什么是AV错误?我该如何调试它?
当你运行程式得到了一个AV(Access Violation)错误的时候,这意味着你的程式正在试图访问一块
不再有效的内存,请注意我所提到的“不再”有效。大多数的情况下,出现这个错误要么是因为你试图访问一块已经被释放的内存,要么是想使用一个还未创建对象的指针。
幸运的是:Win32的内存体系在不同的进程(Process)间使用了独立的地址空间。所以我们可以不必担心会访问到其他的进程中的地址空间而造成破坏,(在Win 16下就有这种潜在的危险).这也就意味着我们能够正确的利用错误对话框中的信息。
当我们得到一个AV错误对话框的时候,将会出现例如:Av at ddress ????的字样,如图:
这个时候把这个地址写下来(如图为:0X4006A620),回到程序中并且打开调试用的CPU窗口,右键选择"Goto Address",你将会发现出错的信息结构。
当然CPU窗口都是以汇编语言(Assembly)出现的.你可能对此不大熟悉。于是你就可以在窗口中滚动看看到底是哪个函数(funtion)调用了它。这样你就可以在这个地方设置断点了(breakpoint).
不幸的是,不是每个错误都是这么容易的捕捉到的。相对而言。指针问题是很难调试的。这里有个常规的法则就是:在删除指针指向的对象以后。请将它置为NULL。因此在调用的时候你可以先看看这个指针是否为NULL,如果是NULL,你可以在这个地方输出一些调试信息以方便你在发生AV错误的时候能精确的找到这个地方。
// ==================================================
译者注:比如这样:
if(pName==NULL)
MessageBox("Pointer pName is NULL","Hint",MB_OK);
这样在弹出这个对话框的时候就可以知道是这个地方错了
// =====================================================
最后一个比较保险的方式就是尽可能的在使用指针的地方设置断点看看是否它为NULL。
译者注:
这篇文章告诉了我们什么是AV,一般产生的原因和如何捕捉等。我觉得上面谈到的只是一些比较通用的法则。实际未必如此。比如大家知道由系统自动销毁的对象其指针未必就是NULL,
而想通过检测指针的值来判断AV的话,这种情况就不适合。还有一个方面就是出现AV的另外一种情况:指针未能初始化(Initalization)并未提到,当然这都要靠写程式的自己防止了。
另外文章中提到的删除对象后把指针置为NULL应该是大力倡导的,这点也是Scott Meyers所提到的,毕竟删除一个NULL指针是安全的,而删除一个已经删除的指针“其结果是不可预测的”.
文章出处:http://community.borland.com/article/0,1410,26406,00.html