我自己用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重复值