Delete出错分析总结(个人总结很到位) 0x0000007ff64426f87e(ucrtbased.dll)处(处于dataa.exe中)引发的异常:

近日在调试C++程序中new class 后delete 出现如下错误:
* 0x0000007ff64426f87e(ucrtbased.dll)处(处于dataa.exe中)引发的异常:0xC0000005:读取位置(0xffffffffffffffff)时发生访问冲突。*

bimage *metric=new bimage(image);
xxxx
xxxx
delete metric;

bimage定义:
class bimage{
pubic:
    bimage();
    bimage(bimage*image){allocate_buf();variable assignment;};
    ~bimage();
private:
    int xx;
    uinit32 *buf[4]; //
    uint32 **p_buf[4];
    bool allocate_buf()
    {
        buf[0]=new uint32[w*h];
        p_buf[0]=new uint32*[h];
   }
}

因为只用到一个通道,故allocate_buf中只对buf[0] 和p_buf[0]分配了空间。
百度了一下delete出错的可能性之后,有帖子说
“初始化什么也没做,并没有指向一块分配的好内存”,我猜想这可能是出错的原因,故改写allocate_buf

    bool allocate_buf()
    {
        buf[0]=new uint32[w*h];
        p_buf[0]=new uint32*[h];
        buf[1]=buf[0];
        buf[2]=buf[0];
        buf[3]=buf[0];
        p_buf[1]=p_buf[0];
        p_buf[2]=p_buf[0];
        p_buf[3]=p_buf[0];
   }

运行后出现
0x0000007ff64426f87e(ucrtbased.dll)处(处于dataa.exe中)引发的异常:0xC0000005:读取位置(0x00321554ddc0e8)时发生访问冲突。
好家伙,果然跟未赋值有关。但是依然有访问错误,继续百度,找到一篇:
”不能重复delete“
buf[1]=buf[0];指针赋值,delete时明细会删除两次啊。再改,赋值为NULL总可以吧

    bool allocate_buf()
    {
        buf[0]=new uint32[w*h];
        p_buf[0]=new uint32*[h];
        buf[1]=NULL;
        buf[2]=NULL;
        buf[3]=NULL;
        p_buf[1]=NULL;
        p_buf[2]=NULL;
        p_buf[3]=NULL;
   }
总算顺利通过运行。填坑完毕。

参考https://blog.csdn.net/tianxia_taiping/article/details/10928927 总结一下Delete 中的坑
Delete出错原因分析:
1.数组首地址被无意更改。例如:int A[10]; A++;
2.作用域不同。例如:在函数A中new的内存 int p = new int;在函数B中delete p,此时函数B不认识标识符p。
3.重复delete。例如:在dll的外部对dll的资源进行delete,有可能dll内部自己做了delete操作,此时会重复delete。
4.new的指针指向不定,未初始化,delete时出错。
5.内存越界。这是最常见的,new的空间太少,使用时超出范围,更改了不属于程序自己的地址上的值。如果更改的地址是系统关键区域,程序会马上崩溃;如果是一般的地址,系统不会马上检测出来,这样就埋了一个bug。
例如:VC分配内存时,除了本身的数据空间外,还会分配额外的管理内存。例如在所分配内存的前后会放置边界标识符0xfdfdfdfd。若越界操作,改变了边界外的值,破坏了管理内存,delete时会失败或卡死。如图所示:0xfdfdfdfd为边界标识符,0xcd 0xcd 0xcd为分配的内存,堆区分配的内存未初始化时,VC填充0xcd。前面的0x00000003为分配的内存大小,0x00000001为内存分配目的,0x000000ab为分配的内存编号

解决方法:
1.当传入的形参是数组时,能加const的就加const,防止在函数内部中的意外操作。
2.内存new和delete时,原则:谁申请谁释放。
3.在delete指针后,将指针置为NULL。例如:delete p; p = NULL;
4.对new申请后的指针变量赋值,或者p=NULL;
5.内存越界情况太多了,不具体说了。一般情况,在new之后,需要判断分配内存是否成功。声明指针后,置为NULL,例如:int *p = NULL;

  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值