C++ 使用delete删除指针后应该做的工作

C++ delete指针以后应赋值为NULL delete p后,只是释放了指针指向的内存空间。p并不会自动被置为NULL,而且指针还在,同时还指向了之前的地址 delete NULL编译器不会报错(因为delete空指针是合法的) 例: 对一个非空指针delete后,若没有赋NULL,若再次delete的话,有可能出现问题。 如下代码 1 int *p = new int(3); 2 delete p; 3 delete p; 用VC编译运行将出现问题。 将其改为: 1 int *p = new int(3); 2 delete p; 3 p = 阅读详情

转自:http://www.cnblogs.com/uniqueliu/archive/2011/07/18/2109778.html

众所周知,最开始我们用new来创建一个指针,那么等我们用完它之后,一定要用delete将该指针删掉。但是,值得注意的是,难道就仅仅是删除这个指针这么简单的么?下面,我们用一个程序来说明这个问题:

01 #include <iostream>
02 using namespace std;
03 int main()
04 {
05     int *p=new int;
06     *p=3;
07     cout<<"将3赋给p的地址后,指针p读取的值:"<<*p<<endl;
08     delete p;
09     cout<<"删除空间后,指针p读取的值:"<<*p<<endl;
10     long *p1=new long;
11     *p1=100;
12     cout<<"创建新空间后,指针p中保存的地址:"<<p<<endl;
13     cout<<"指向新空间的指针p1保存的地址:"<<p1<<endl;
14     *p=23;
15     cout<<"将23赋给p的地址后,指针p读取的值:"<<*p<<endl;
16     cout<<"将23赋给p的地址后,指针p1读取的值:"<<*p1<<endl;
17     delete p1;
18     return 0;
19 }

       在上面这个程序中,我们在第8行就将指针p利用delete删掉了。但是,我们来看看程序的输出结果:

      对照着上面的程序,我们来分析一下这个输出。首先,我们在程序的第5行初始化了一个指针p。之后输出指针p读取的值。由于第6行的原因,程序肯定会输出3了。之后,我们在程序的第8行删除了这个指针p。但是我们惊奇的发现,在程序的第9行竟然可以输出指针p读取的值。我们不是已经把它删了么?其实不然,debug,上图:

      从监视窗口中,我们可以看见虽然程序的第8行已经将指针p删除了,但是在监视窗口中p仍然存在,只是*p所指向的值不再是原来的3了,而是一个随机数。这里就说明了一个非常重要的概念:我们在删除一个指针之后,编译器只会释放该指针所指向的内存空间,而不会删除这个指针本身。

      然后我们接着往下分析。在程序的第10行我们又创建了一个long型的指针p1。在12行与13行的输出中我们惊奇地发现,指针p保存的地址居然和指针p1保存的地址一模一样!这个就说明了指针p和指针p1都指向内存的同一个地方!!!出现这种状况的原因其实是由于编译器。编译器默认将释放掉的内存空间回收然后分配给新开辟的空间。所以在第11行由于我们新开辟了一个可以保存long型变量的空间并且由p1来指向它,那么这里的p1指向的其实就是在程序第8行释放掉的内存空间,即p指向的内存空间!所以,这就导致了两个指针同时指向同一个内存空间。这是多不安全的一件事情啊!要知道,我们是把指针p删了的啊!如果再重新对*p进行赋值操作,那么不是会连着*p1一起改动么?

      果然,让我们担心的事情出现了。我们明明在程序的第11行中定义了*p1的值为100,但是在输出上面,指针p1读取的值竟然也是23。这个原因就是因为野指针p造成的。我们可以看到,在程序的第14行我们将23赋给了*p。又由于p和p1指向的是同一块内存单元,所以在这里相当于也将p1所指向的内存单元中的值(原来是100),改成了23!这样必然会导致程序的出错!

       那么我们就不禁要问了,对于这种由于野指针造成的问题,有没有解决的方法呢?答案当然是有的了。我们只需要牢记下面这句话:

在删除一个指针之后,一定将该指针设置成空指针(即在delete *p之后一定要加上: p=NULL)

      我们来看一下在stdio.h中关于关键字NULL的定义:

1 /* Define NULL pointer value */
2  
3 #ifndef NULL
4 #ifdef __cplusplus
5 #define NULL    0
6 #else
7 #define NULL    ((void *)0)
8 #endif
9 #endif

      注意上面定义的第5行。这里其实就说明了NULL就是0。也就是说,我们在删除完指针p之后,一定要把它变成空指针!只有这样,才会杜绝上面程序中出现的野指针的错误。

p.s. 对于NULL的应用,我们不应该仅限于上面的方法,还可以应用NULL来判断指针是否初始化成功了,如下例if中的判断方法:

01 #include <iostream>
02 using namespace std;
03  
04 int main()
05 {
06     int *p=new int;
07     if (p==NULL)
08     {
09         //判断指针p是不是空指针,如果是空指针,那么程序在这里就应该报错
10         //报错的方法有很多,比如说返回一个ERROR值:
11         //return ERROR;
12     }
13  
14     //判断了操作成功之后我们才能进行一系列的操作
15     //...
16  
17     //用完指针p之后,一定要将其删掉。这样可以杜绝野指针的存在
18     delete p;
19     //删除指针p之后,一定要加上下面这句话,免得成为野指针
20     p=NULL;
21 }

         好了,下次一定要记住,在分配空间给指针之后,一定要用NULL来判断一下是否成功了。然后在删除这个指针的时候,也要用NULL来赋给指针,杜绝成为野指针!

C++new和delete运算符 1)new int *pi = new int(5); 实际上是由两个步骤完成的: 1.通过适当的new运算符函数实例,配置所需内存:int *pi = __new(sizeof(int)); 2.将配置得来的对象设置初值:*pi = 5; 更进一步,初始化操作应该在内存配置成功后才执行: int *pi; if(pi = __new(sizeof(int))) //(__new即下面会说到的operator new) *pi = 5; 以constructor来配置一个class object的情况类似 阅读详情

相关推荐

MATLAB双目相机标定:从工具箱实战到参数精解

本文详细讲解了使用MATLAB进行双目相机标定的完整实战流程与参数精解。从拍摄合格的棋盘格图像、设置关键参数(如径向畸变系数),到分析重投影误差、优化结果并正确导出和使用内外参,提供了从操作到原理的全面指导,帮助读者为立体视觉应用奠定精准基础。

weixin_29041767的博客 259

C/C++ 指针删除的几个细节

在C/C++中,当指针需要删除时,对于new的指针,调用delete就可以删除  比如 : int* p = new int(17); delete p; 有时候为了避免使用错误,一般在delete之后,将p置为NULL,即: int* p = new int(17); delete p; p = NULL; 有时候为了方便及统一处理指针的申请及释放,一般放到将删除

玉宇逍遥 5491

游戏开发实战:5种AOI算法对比(九宫格 vs 灯塔 vs 十字链表)

本文深入对比了游戏开发中五种主流AOI算法(九宫格、灯塔、十字链表等)的性能与适用场景,帮助开发者根据项目规模选择最优解决方案。通过详细的技术分析和实战数据,揭示不同算法在万人同屏等极端场景下的表现差异,为MMORPG等大型多人在线游戏提供关键性能优化指南。

weixin_29268385的博客 474

利用LDA进行主题建模,用困惑度和一致性曲线选取最优主题数

如果困惑度和一致性曲线效果图较好,确定了主题数量后,再单独跑一下2里面的程序。2中topic为5是我主观设置的,不一定为最优。

m0_56327159的博客 4223

工业自动化进阶:西门子 S7-1200 PLC 调度 AGV 实现精确定点移动

本文介绍了基于西门子S7-1200PLC的AGV调度控制系统设计,包括系统架构、硬件选型和PLC程序设计。系统通过PROFINET通信实现PLC与AGV的数据交互,采用状态机控制逻辑实现任务管理、运动控制和闭环位置校正。重点阐述了通信协议实现、梯形图核心逻辑及系统调试优化方法。实际应用案例显示,该系统定位精度达±3mm,显著提升了物料配送效率。该方案为工业自动化升级提供了可靠的技术支持。

qq_52407556的博客 1887

Cpp指针的delete操作 - 小记

关于Cpp中delete指针并防止野指针出现的操作顺序的效果对比验证

LXT13592800607的博客 1668

置顶必读(1) | 《YOLOv26实战:从入门到深度优化》专栏导读与完整目录导航(持续更新中)

🏆 本文收录于 《YOLOv26实战:从入门到深度优化》 专栏。 本专栏系统梳理并持续复现 YOLOv26 官方特性、核心改进、多任务支持、部署优化与行业落地,内容坚持 持续更新 + 深度拆解 + 工程落地导向,不仅讲“怎么用”,更讲“为什么这样设计、如何真正落地到项目中”。

**My Coding Family** 9万+

【C++】指针什么时候必须delete,什么时候可以不delete

栈中的变量,是由程序自动进行管理的,当变量作用域结束后,程序就会自动释放,因此其内存区域不需要手动delete。所以,栈和堆的设计,是为了保证程序调度能高效的进行,像函数调用这种,在程序中是无时不刻都在进行的,必须保证效率。除了存放大型数据,堆的另一个作用,是可以数据共享,多个函数中的指针,可以访问同一份数据。堆和指针的设计,就是为了把栈中不必要的数据,单独放到一个垃圾堆中去,从而保证栈的高效。像数组,大的内存区域,复杂对象,我们则会通过new或malloc的方式,存到堆内存中。

天天向上 Up Up Up (*^▽^*) 5213

芒果YOLO11改进44:主干Backbone篇之MobileViT::结合最新 ICLR2022 顶会|轻量通用的MobileViT结构(一)Transformer,轻量级、通用且移动友好的视觉转换

MobileViT::结合最新 ICLR2022 顶会|轻量通用的MobileViT结构(一)Transformer,轻量级、通用且移动友好的视觉转换

包括YOLOv5、YOLOv7、YOLOv8等模型改进 370

20、自定义用户窗体:从创建到使用

本文详细介绍了在Excel VBA中创建和使用自定义用户窗体的完整过程,涵盖从窗体设计、控件添加与属性设置,到事件处理程序编写及宏调用的各个环节。通过实际示例讲解了如何实现文本大小写转换和员工信息录入等功能,并深入解析了常用控件的属性与事件机制。同时提供了控件命名规范、快捷键使用、布局技巧等实用建议,帮助读者构建高效、交互性强的VBA用户界面。

h0i1j2k3l的博客 131

析构函数里对指针成员调用delete[转载]

大多数情况下,执行动态内存分配的的类都在构造函数里用new分配内存,然后在析构函数里用delete释放内存。最初写这个类的时候当然不难做,你会记得最后对在所有构造函数里分配了内存的所有成员使用delete。 然而,这个类经过维护、升级后,情况就会变得困难了,因为对类的代码进行修改的程序员不一定就是最早写这个类的人。而增加一个指针成员意味着几乎都要进行下面的工作: ·在每...

weixin_30611509的博客 279

【国密】基于SM2的协同签名与协同解密方案

两方协同签名指客户端与服务端协同完成签名、验签操作,具体实现方案参考了信工所专利[3]。在业务应用中,两方或多方的协同签名一般采用门限签名方案可以用来构造。门限密码算法在多方协作的相关场景中应用十分广泛,可以实现数据联合授权、认证、密钥安全恢复、密钥安全交换等需求,在诸多分布式多方计算协议中均可见其身影。在上述两方协同签名方案中,最巧妙的地方在于签名值s分量的构造,通过一些列数学变换,得以恢复。以下从两方协同签名方案介绍入手,介绍门限密码在协同签名中的应用。解决上述问题的关键在于门限密码算法的巧妙构造。

听雨草堂 8388

C++new与delete的使用

C++的new与delete 1.new的运算符用法(关键字) 2.new的函数用法 3.定位new 4.new创建对象 5.delete 6.对于内置类型new/delete/malloc/free可以混用 7.使用注意事项

Mi-ronin的博客 1万+

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

C++ delete指针需置空

delete指针之后,一定要给指针赋值为空,不然会引起程序崩溃。 T* p = new T(); delete p; // ... p->func(); // crash if (p) { p->func(); // crash too } 以上代码,因为指向的内存已经被释放,导致后面的调用失效,这种情况导致程序崩溃的原因会非常难找,而且出错的位置很难定位,开发时往往还容易遇到很多这种情况。 那么delete到底做了什么动作呢? delete指针只是释放了那个指针原本所指的内存而已,并没

YYY_77的博客 8171

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

C++指针delete后还要置为null

众所周知,最开始我们用new来创建一个指针,那么等我们用完它之后,一定要用delete将该指针删掉。但是,值得注意的是,难道就仅仅是删除这个指针这么简单的么?下面,我们用一个程序来说明这个问题:[cpp] view plain copy#include &lt;iostream&gt;  using namespace std;  int main()   {      int *p=new in...

qq_36570733的博客 3万+

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

C++ 使用delete删除指针

众所周知,最开始我们用new来创建一个指针,那么等我们用完它之后,一定要用delete将该指针删掉。但是,值得注意的是,难道就仅仅是删除这个指针这么简单的么?下面,我们用一个程序来说明这个问题:   #include 02 using namespace std; 03

xjianm的专栏 3万+

在C++中Delete指针的用法

在 C++/C 语言中,使用 `delete` 删除指针所指向的内存后,并没有系统自动将指针设置为 `nullptr` 的机制。尽管如此,将指针设置为 `nullptr` 后使用 `delete` 是一个好习惯,因为这可以避免野指针问题。` 这一步,尤其是在简单的示例或短代码片段中。- 在某些情况下,开发者可能知道在 `delete` 之后不会再使用该指针,因此省略了设置 `nullptr` 的步骤。- 有时,开发者可能忘记了将指针设置为 `nullptr`,或者认为这不是必要的,这可能导致野指针问题。

printfLILEI的博客 1017

C++delete一个指针之后为什么要设置为nullptr

C++delete一个指针之后为什么要设置为nullptr 本文转载自:使用delete 删除指针,真的删除了吗 我们在用动态内存分配时,可以使用new在动态内存中为对象分配空间并返回一个指向该对象的指针,比如说int* ptr = new int(1);,在自由空间构造一个int型对象,并返回指向该对象的指针给int* ptr。(注意:ptr只是一个变量,就像是int a=1;中的a一样,不过a是整形变量,而ptr是指针变量)。 为了防止内存耗尽,在动态内存使用完毕后,我们必须将其归还给系统。通过dele

qq_43525962的博客 5367

使用delete 删除指针,真的删除了吗

delete指针我们在用动态内存分配时,经常是用new来定义一块内存空间,比如说 int* p = new int(1);这时会在堆上分配一块内存,当作int类型使用,内存中存储的值为1并将内存地址赋值给在栈中的int*类型的p。(注意:p只是一个变量,就像是int a=1中的a一样,不过a是整形变量,而p是指针变量)当我们不用p指针时,往往需要用delete p将其释放,我们需要注意的是释放一个...

ai_yue的博客 9594

c++ delete指针删除的是啥

T* p=new T();//p指针存放在栈中、new出来的对象存放在堆上 p指针指向该对象 delete p; //delete p 并不是删除P而是抹除p指向的堆上的对象。 //delete p 后p指针其实还是存在的 p=Null; //但是为了不让p指向已经被抹除的对象 赋值给NULL; ...

qq_15735643的博客 1997

C++使用delete删除指针注意事项

#include <iostream> using namespace std; // 我们在删除一个指针之后,编译器只会释放该指针所指向的内存空间 // 而不会删除这个指针本身,所以要NULL一下将这个指针变成空指针,防止变成野指针 // 编译器默认将释放掉的内存空间回收然后分配给新开辟的空间。 int main(void) { int *p = new int; ...

qwer1542112264的博客 1044

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

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

biao2488890051的博客 3421

C++之我见--delete指针

开篇之前温故一下关于指针的几个小点: 指针本身也是变量,特殊之处在于它是指向一个内存地址的变量 既然是变量,那么它在内存中也有地址 指针p本身地址:&p 指针p指向地址:p 指针p指向地址内值:*p delete指针 指针delete掉之后需要置NULL 甭管为什么,记住总没错。 下面解释下为啥? int *pp = new int; *pp = 1; cout &lt...

我爱我家 3359
上一篇: const int *p,const * int p,int const *p
下一篇: vim设置
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值