问题源自一段简单的代码:
void main()
{
char *p = new char;
cin>>p;
cout<<p[2];
delete p;
}
在以上代码中,如果你输入:abcd,那么如你所望,你会看到"正确"的输 出"c"。但是会有错误提示出现:
Debug Error!
Program: test.exe
DAMAGE: after Normal block(#64) at 0x003429f8
更离奇的是,如果将代码改为如下的代码:
void()
{
char *p = new char;
cin>>p;
cout<<p;
delete p;
}
如果只输入一个字符a,那么依然报错。是不是奇怪,分配了一个字符,输入了一个 字符,那么错在哪里? 注意,最开始那行Debug Error!说明这是在Debug编译模式下才有的 提示,如果你换到release频道,那么此提示不再出现,你成功得到了"c",仿佛 程序一切正常。
一个奇怪的现象是,如果去掉delete p这条语句,这个运行时错误消失了,甚至你在 debug模式下也看不到这个提示。 问题何在?
以前我遇到过这种情况,分析后归结为一个结论:在debug模式下系统有一定的机制侦测 到内存的非法访问。然后就放过这个问题。这个结论说了等于没说,关键在于,这种机制的 具体运做过程。这次我下了狠心,不入虎穴,焉得虎子。我决定追进源代码里边去。 把编译 环境设置成debug模式,很显然,问题出在delete p上,在这条语句设置断点,按F5,程序运 行到这条语句前自动暂停,然后按F11。
Welcome to the Source Code World!
首先来到DELOP.CPP文件中,这个文件短小精悍,只有一个函数
void __cdecl operator delete(void *p) _THROW0()
{ // free an allocated object
free(p);
}
没有任何有用的信息,那就继续追进free(p)里。 不一会,我们追到了DBGHEAP.C 中,你从文件名可以看出,这是在debug模式下才能进入的文件。