Gan*_*ant 10 c++ memory crash pointers visual-c++
我这里有一个非常简单的C++代码:
char *s = new char[100];
strcpy(s, "HELLO");
delete [] s;
int n = strlen(s);
Run Code Online (Sandbox Code Playgroud)
如果我通过按F5(开始调试)从Visual C++ 2008运行此代码,这总是导致崩溃(访问冲突.)但是,在IDE外部启动此可执行文件,或使用IDE的Ctrl + F5(启动而不调试)不会'导致任何崩溃.有什么区别?
我还想知道是否可以稳定地重现因访问已删除区域而导致的访问冲突崩溃?现实生活中这种崩溃难得一见吗?
Ste*_*ows 19
通过删除指针访问内存是未定义的行为.您不能指望任何可靠/可重复的行为.
很可能它在一种情况下"有效",因为字符串仍然"坐在那里"现在可用的内存中 - =但你不能依赖它.VS使用调试值填充内存,以帮助强制崩溃以帮助查找这些错误.
不同之处在于调试器,调试库以及以"调试"模式构建的代码都喜欢破坏应该破解的东西.您的代码应该中断(因为它访问它不再是技术上拥有的内存),因此在编译调试并在调试器中运行时会更容易破解.
在现实生活中,通常不会得到如此不明确的通知.所有那些让它们在调试器中应该破坏的东西......那些东西很贵.所以在发布时没有严格检查.您可能能够在100次中获得99次以释放一些内存并立即访问它,因为运行时库并不总是立即将内存交回操作系统.但是第100次,要么内存消失了,要么另一个线程现在拥有它,你得到的字符串长度不再是一个字符串,而是一个252462649字节的crap数组,它一直运行到未分配的(因此非存在,只要你或运行时应该关心)内存.并且几乎没有什么可以告诉你刚刚发生了什么.
所以不要这样做.一旦你删除了某些东西,就认为它已经死了.或者你将浪费一半的时间追踪heisenbugs.
取消引用后面的指针delete是未定义的行为 - 任何事情都可能发生,包括但不限于:
确切的结果将取决于多种因素,其中大多数因素是您无法控制的.首先,你最好不要触发未定义的行为.