读书人

为啥release会崩溃的程序,release的调

发布时间: 2012-06-20 20:37:21 作者: rapoo

为什么release会崩溃的程序,release的调试模式却不崩溃。
我写了一小段代码来看程序遇到非法操作的时候如何崩溃。

我new了一个C的对象,操作它的pi数组的时候故意越界,覆盖了pm指针。
因此通过pm指针调用m*对象的时候,因为this指针是非法的,所以运行崩溃了,在release模式下。

但是我发现在release模式下也可以F5调试,这种情况下无论如何也不会崩溃。我看打印出来的指针分配的大小和偏移量,和我直接release运行的值是一样的。
我知道debug模式分配内存会有很多前后保护的空间,奇怪的是为什么release模式调试的时候不会崩溃呢?

源代码如下:

C/C++ code
#include "stdafx.h"#include <algorithm>class C{public:    C(){        nCount=3;        pi=new int[1];    }    ~C(){delete [] pi;}    int *pi;    int nCount;};class my{public:    int k;    my():k(2){}    virtual int GetK(){        return k;    }};int main(void){    C* pc=new C;//new+构造函数可否带初始化列表    my* pm=new my;    auto len=std::distance(pc,(C*)pm);    printf("%p,%p,%p\n",pc,pm,&(pc->pi[len]));    pc->pi[len]=0;//覆盖了pm!    int kk=pm->GetK();//这句话会导致崩溃。但是release模式调试不崩溃,debug更不崩溃    //printf("%d\n",kk);    delete pm;    delete pc;    return 0;}



[解决办法]
不是在delete pm;崩溃的吗?
[解决办法]
我试了一下VC6下都崩的
[解决办法]
C/C++ code
C* pc=new C;//new+构造函数可否带初始化列表 ----> 这是类不是结构体,不可以这样初始化的,需要调用构造函数的C* pc=new C();//new+构造函数可否带初始化列表//同理销毁类对象之前需要确保调用了析构函数//通常的方法是自定义一个初始化函数比如CreateInstance();并自定义一个销毁函数,让它在析构函数里调用。//比如CWnd::Create()就是这样的初始化函数,里面包含了new操作的
[解决办法]
探讨

引用:

不是在delete pm;崩溃的吗?


不是,去掉了delete pm;也还是崩溃

[解决办法]
多数是空指针的情况会发生吧。
[解决办法]
个人猜测

可能和编译器分配内存的字节对齐长度有关
如果两个new出来的内存块不是完全紧挨着的话,上面的程序就不一定越界

在内存窗口 仔细看看两个分配出来的内存块的关系, 单步调试下看看内存的变化情况
[解决办法]
没说一定要崩的,我曾经试过VC6将一个指针删除N次,结果每次都正常调用析构函数,应用程序正常结束,运行了N次也没崩。

读书人网 >VC/MFC

热点推荐