添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

我自己用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 指针两次会怎么样? - 知乎 (这里面讲了大量的讨论,可以看看,挺有意思)

指针 非空时, delete 运算只释放 指针 所指的地址空间,不会判断空间是否被占用, delete 结束后不会将 指针 赋值为空。 对同一非空 指针 delete 多次 ,只有第一次 delete 被正确执行,之后的 delete 全部发生异常。 对空 指针 delete 多次 可以正常执行。 良好的习惯是, delete 运算后手动将 指针 赋值为空。 测试代码: #include <iostream> using ... 文章目录引言:(一)new 对象 过程(二) delete 对象 过程 我们往往使用new delete 对象 ,这个过程被编译器藏得很深,但是这个过程具体是什么?和 C语言 的malloc、free有什么样的区别和联系呢?那就先看看下面这个点类的设计,本文将通过这个代码进行new和 delete 对象 的步骤的深入。 #include <iostream> using namespace std; class Point public: Point(){} Point(int r, int c) 1. C++ delete 顺序 在 一个 类中定义了 一个 结构体,并且声明了这个结构体的 一个 对象 ,在这个结构体定义中又声明了另外两个类的 对象 。并且在该类(GMS)的构造函数中分别new,如下所示: struct GMS::MDL MM* m_pMM; TaskPlan* m_pTaskPlan; pimpl_ = new MDL; 指针 非空时, delete 运算只释放 指针 所指的地址空间,不会判断空间是否被占用, delete 结束后不会将 指针 赋值为空。 对同一非空 指针 delete 多次 ,只有第一次 delete 被正确执行,之后的 delete 全部发生异常。 对空 指针 delete 多次 可以正常执行。 良好的习惯是, delete 运算后手动将 指针 赋值为空。   #pragma warning (disable : 4786)#include #include #include #include using namespace std;class A{public: ~A() { } void pOut() {  doOut(); } virtual void doOut() = 0;};class BA: public A{pub 本文介绍分析一种 多次 delete 动态内存的情况。说是典型,是因为这个问题已经在我两个同事身上发生过;说是隐秘,是因为一旦发生问题,靠肉眼很难确定原因。 不同于 C语言 通过malloc和free等函数实现动态内存的分配和释放, C++ 引入了new和 delete 运算符实现。基本的用法如下: int* p = new int; delet...      建一张示例表并插些数据看看吧。          mysql> CREATE TABLE `visitor_province_yn` (           ->   `id` INT(11) NOT NULL AUTO_ 0x00 简介在入门 c 语言 时我们都知道 一个 常识:通过 malloc() 动态申请的内存在使用完之后需要通过 free() 释放;那么如果因为程序设计不当,导致这块堆内存释放之后,再释放一次会发生什么呢?看起来这个操作似乎很愚蠢,但是 double free 的确是现代软件中十分常见的一种二进制漏洞。我将通过 一个 例子来说明 double free 可能造成的危害。这个例子是曾经的一道 0ctf ... delete 删除重复记录方法假设表名为Tbl,表中有三列col1,col2,col3,无主键。1、通过创建临时表可以把数据先导入到 一个 临时表中,然后删除原表的数据,再把数据导回原表,SQL语句如下:creat table tbl_tmp (select distinct* from tbl);truncate table tbl;//清空表记录insert into tbl select * fr... 时常有这样的case: DB实例运行一段时间后,发现需要给1个table中的某(些)字段加unique 约束, 但创建unique constraints(或 index)时, 报出 DETAIL: Key (col)=(value) is duplicated ! 此时就需要先按照一定逻辑将重复数据仅保留1条, 将冗余的 delete delete 数据, 重点自然在于定位所有待 delete 的row, 或需要保留的row. 以假设业务要求要保留如下test表中每组info重复值