• c/c++一个指针delete两次的后果


    C++危险就在内存泄漏内存管理,但是也是迷人的地方。一般这些指针导致的内存问题都很难发现,除非编程经验非常丰富,下面说的就是一个例子。

    我的测试

    我自己用qt亲自测试,delete两次同一个wid*两次,第一次是正常删掉这个wid,没问题,第二次,软件直接崩掉(直接运行测试的,且控制台打印pure virtual method called),或者提示段错误(单步调试测试的)。这里我就是直接连续delete的两次,所以我得肯定没有发生内存覆盖情况的,整个运行情况就是这样。所以不管有没有内存覆盖,总之同一个对象delete两次(这就是安全漏洞,一个研究话题),就是不对的,这个说明程序本身逻辑和架构是有问题的。

    网上给出了一个怎么用指针的排序, 本着程序稳健运行的宗旨,从推荐指数高到低:(https://www.zhihu.com/question/38998078/answer/1015536330)

    0.不用指针:(贤者思维)为什么非用指针不可呢,符号长得丑不说,还徒增心智负担

    1.智能指针:(智者思维)完全无心智负担,自动管理资源生命周期和多引用基数,所付出的仅点微量的内u才能和初始化开销。

    2.裸指针:前判断 delete后置零---项目经理思维,100%规避隐患,但代码不好看,心累呀

    3.裸指针:前不判断delete后不置零---软件测试思维,多数情况下可以提前暴露逻辑问题,代码比2好看点,但调试时还是心累

    4.裸指针:前判断delete后不置零---逗逼思维,和2有区别么

    5.裸指针:前不判断delete后置零---IDIOT思维,出现软件看上去运行正常但实则巨大隐患的可能性比3更大(参考表格)。

    解决方法

    看了网上的讨论,尽量避免这个问题的方法如下:

    • delete后把这个指针变量赋值为nullptr,因为delete再次删除的时候,delete 0,就是没问题的了,而且也能让别的地方知道这个指针是否被delete过了,也还是很安全的。
    • 用智能指针,这个我用不惯

    其它比较好的讲解(仅供参考,对不对自己测试才行)

    C++ 里 delete 指针两次的后果分为3种情况:

    1)如果释放的这部分内存没有被复用,设计时cookie中有标记这部分内存已经释放,会检测到重复释放,在debug版本中显示告警信息,在正式版中什么都不会发生。

    2)如果释放的这部分内存被复用了,new的新指针不是与旧指针相同的地址, 那么,就取决于内存库的设计了。我们的设计是一种集中式的一大片cookie, 旧的cookie一般不会被覆盖,第2次 free 会检测到重复释放,在debug版本中显示告警信息,在正式版中什么都不会发生。多数内存库是分散的cookie, 旧的cookie可能会被其它用户数据覆盖,因此, 结果无法预料(如果没有被覆盖, 那么也会检测到重复释放)。

    3) 如果释放的这部分内存被复用了,new的新指针是与旧指针相同的地址,那么把新申请的使用中的地址释放掉了,结果无法预料,可能什么事情都没有发生,也可能崩溃,还可能这部分地址又被第3个模块申请地址所复用,导致更离奇的bug, 情况很复杂,很难查。

    彻底解决C++里 delete 指针两次的办法很简单, 就是不用 new / delete。全部使用智能指针,unique ptr / shared ptr( 我们还有自研的local ptr, 等效于内部不使用atomic的shared ptr, 只用于单线程或者某个线程内部,性能略高于 shared ptr ), 可以完全彻底杜绝此类问题的发生。

    C++11以后,只要推广使用智能指针,新写的代码应该不存在 delete 指针两次的问题。

    参考 https://www.zhihu.com/question/38998078/answer/2020816965

    C++ 里 delete 指针两次会怎么样? - 知乎 (这里面讲了大量的讨论,可以看看,挺有意思)

  • 相关阅读:
    【SpringBoot】几种常见的数据脱敏方案
    信息系统项目管理师第四版学习笔记——项目绩效域
    【英语语法】so
    【LeetCode】21. 合并两个有序链表
    c++ 原子变量-Memory fence
    再有人问你虚拟机连接问题,把这篇文章丢给他
    Yew应用中如何获取<textarea/>的值?
    AndroidJetpack应用指南学习笔记13--DataBinding的简单使用
    c++对接CAT1400
    什么是邮件签名证书?
  • 原文地址:https://blog.csdn.net/kangkanglhb88008/article/details/127559024