析构或删除对象时应该注意的问题

C++对象析构顺序详解:从静态变量到智能指针的崩溃陷阱与调试 在C++编程中,对象生命周期管理是构建健壮软件的核心。理解对象的构造与析构原理,特别是存储周期(如自动、静态、动态)如何决定其生死,是避免资源泄漏和未定义行为的基础。这项技术的价值在于确保程序退出时的确定性与可预测性,对于开发长期运行的服务、管理复杂单例或设计可复用库至关重要。应用场景广泛,从防止程序退出时的Segmentation fault崩溃,到解决智能指针循环引用导致的内存泄漏,再到多线程环境下安全清理共享资源。本文聚焦于C++中静态变量、全局对象、继承链以及智能指针等复杂场景下的析构顺序问题,通过 阅读详情
    这一个星期以来,一个莫名其妙的bug一直困扰着我,让我寝食难安。。
  1. class test
  2. {
  3. private:
  4.     CMsvEntry *iEntry;
  5.     CMsvSession* iSession;
  6.     S3DummyObserver* iObserver;

  7. public:
  8.     test()
  9.     {
  10.         iObserver = new S3DummyObserver;
  11.         iSession = CMsvSession::OpenSyncL(*iObserver);
  12.         iEntry = CMsvEntry::NewL(*iSession, KMsvRootIndexEntryId, TMsvSelectionOrdering(KMsvNoGrouping,EMsvSortByNone,ETrue));
  13.     }
  14.     ~test()
  15.     {
  16.         delete iSession;
  17.         delete iEntry;          // 异常            
  18.         delete iObserver;
  19.     }

  20. };
上面这段代码是用在message里面,创建一个entry。看起来如此简单的一段代码,却会在析构中产生异常。我把析构函数清空还是会产生一样的问题,会panic掉。
开始以为是没有用symbian的CleanupStack的原因,但假设了很多种情况,都不对。刚才灵感一来,想会不会是delete顺序的原因,于是将析构的代码改成下面这样,问题就解决了。
  1. ~test()
  2. {
  3.      delete iEntry;     // 正常
  4.      delete iSession;       
  5.      delete iObserver;
  6. }
所以猜测原因是先删除了iSession之后,iSession内容为空,而在iEntry的析构中对iSession进行了操作,导致panic。
现在发现是这种小问题导致我迷惑了一个星期,真冤!!!

在这里总结一些析构或删除对象时应注意的问题:
  1. 注意删除顺序,最好以栈方式申请和删除。
  2. 如果删除出错,则考虑对象的析构函数是不是private型的。
  3. 如果是用CleanupStack,则应参考 Inside CBase class - six essential questions
虚析构与纯虚析构 现在有两个类A,B。A是B的父类,此时A,B的构造、析构、拷贝函数都是public,B中有一个指针变量,B在构造函数中为这个变量申请内存空间(new),在析构函数中释放这个内存(delete)当在执行。明显可以看到没有调用Apple的析构函数,那么Apple中的指针变量a_name申请的内存空间就不会释放,那么就会造成内存泄漏。那么我们该怎么样防止这种内存泄漏呢----使用虚析构或者纯虚析构函数可以解决。不可以,因为在后面释放子类占用的空间时,需要用到父类的析构函数,所以必须实现纯虚析构函数。 阅读详情

相关推荐

halcon 深度学习标注_Halcon deep learning之目标检测笔记(一)

设置输入输出的路径输入路径有两个,一个是图像路径HalconImageDir,一个是Json文件路径PillBagJsonFile。这两个参数用于后续在图像路径中读取coco文件。输出路径首先定义一个新的文件夹路径,用于存放样本和模型文件等数据。设置基于深度学习的目标检测模型的路径,该模型文件以.hdl结尾。设置样本数据文件夹ExampleDataDir:'detect_pills_data'数据...

weixin_27885313的博客 2699

堆中创建对象/删除对象-析构函数

#include using namespace std; class human { public: human() { cout<<"构造函数执行"<<endl; } ~human() { cout<<"析构函数执行"<<endl; } }; int main() { human *p =new human;//堆中创建对象 delete p;//删除的是对象 return 0; }

无穷山色 929

vue 插件vue-awesome-swiper实现 三张图片,左右两边显示一半的效果的示例

希望我的愚见能够帮助你哦~,若有不足之处,还望指出,你们有更好的解决方法,欢迎大家在评论区下方留言支持,大家一起相互学习参考呀~

weixin_50450473的博客 3249

delete和析构函数间的关系及细节

http://blog.sina.com.cn/s/blog_78c5ff950102vjoe.html 个人心得:先看以下代码 #include #include using namespace std;   class shape  {  public:  char x;     shape(char m)      {        x=m;      c

sundingh的博客 1613

Label Studio 图像分割自动标注接入教程:从模型预测到一键上传 Predictions

这篇文章详细介绍了如何使用Label Studio进行图像分割任务的自动标注流程。主要内容包括: 环境准备:安装Label Studio和模型推理依赖 项目配置:启动Label Studio服务,创建项目并配置BrushLabels标注界面 数据准备:导入待标注图片,获取API访问凭证 模型推理:运行训练好的分割模型生成预测mask 结果上传:将预测结果转换为Label Studio格式并通过API上传为Predictions 文章提供了完整的操作指南,包括: 详细的命令行参数说明 推荐的项目目录结构 标注

. 451

VS Code配合Prettier自动格式化代码

每次修改 .prettierrc.cjs 配置文件后,如果发现保存代码时格式化没有生效,可能是 VS Code 插件缓存未及时刷新。建议此时重启 VS Code,确保新的配置被正确加载并生效。

分享技术,分享经验 7423

c 语言中析构函数,c – 如何通过析构函数方法删除对象(类)

我想知道是否可以通过析构函数方法删除对象?我班级的构造函数和析构函数:class cal{public:cal(){days = 0;day = 1;month = 1;year = 1300;leap = true;};~cal(){delete this;}}*calendar = new cal;如何通过类删除此指针?P.S我忘了写下面的代码cal *calandar = new cal[]...

weixin_33204286的博客 446

Unity游戏开发实战:用Flow Field实现RTS百人军团流畅寻路(附完整代码)

本文深入探讨了在Unity中利用流场寻路技术解决RTS游戏大规模单位移动性能瓶颈的实战方案。通过解析从Dijkstra算法生成成本场、积分场到最终向量场的核心原理,并结合分块、缓存及与DOTS/ECS架构集成的优化策略,实现了百人军团的流畅群体寻路。文章提供了完整的代码示例,助力开发者构建高性能的RTS寻路系统。

weixin_28363123的博客 587

Qt对象树原理_8注意2缺陷1迷惑_析构调用顺序

可以看到上述代码中,new的对象没有手动释放,其原理就是对象树。下图是一个对象树,win是窗口,Topic、obj是小控件。堆区:delete的对象及其所有子对象,按顺序从父对象到子对象调用析构函数。(与创建顺序无关)栈区:不允许delete。...

Jasper的博客 1769

Dataworks实现接口调用

在本地linux虚拟机(不用在意linux版本),安装Anaconda后配置对应的虚拟环境,将虚拟环境的python包整体打包(路径一般为:~/anaconda/envs/env_name/lib/pyyhon3.7/site-packages):上传资源,将第三方包上传至dataworks(注意:所有上传文件均要打包上传,直接上传文件会乱码导致无法使用):PyODPS,其中PyODSP2的python版本为2.7,PyODSP3的python版本为3.7。:在PyODPS中引用资源,然后开发接口。

hutc_Alan的博客 1681

结构力学本构模型:复合材料模型:复合材料热力学行为技术教程_2024-08-07_06-54-53.Tex

热塑性复合材料是一种由热塑性树脂基体和增强纤维组成的复合材料。与热固性复合材料不同,热塑性复合材料在加热时可以软化,冷却时硬化,这一过程可以重复进行,因此它们具有可回收和可再加工的特性。热塑性树脂,如聚酰胺(尼龙)、聚碳酸酯、聚醚醚酮(PEEK)等,与碳纤维、玻璃纤维等增强材料结合,可以制备出具有高强度、高刚度和良好耐热性的复合材料。热粘弹性理论是研究材料在温度变化和时间依赖性载荷作用下的变形和应力响应。复合材料,由于其独特的微观结构,展现出复杂的热粘弹性行为。

808

C++ 容器中存入”指针“及对象析构问题

[转]C++ 容器中存入”指针“及对象析构问题  (2012-09-20 23:32:20) 转载▼ 标签:  杂谈 分类: C相关 【转自】:http://blog.sina.com.cn/s/blog_4b3c1f950100kgps.html 一般地当我们只想知道一个值是否存在时,set 最有用处;希望存储也可能修

jfkidear的专栏 1万+

ANSYS——“There is at least 1 small equation solver pivot term”问题的解决办法

ANSYS——“There is at least 1 small equation solver pivot term”问题的解决办法

python_AI_fans的博客 1万+

第8.18节 Python类中内置析构方法__del__

一、 引言 基本上所有支持OOP设计的语言都支持析构方法(也称析构函数),析构方法都是在对象生命周期结束时调用,一般用来实施实例相关生命周期内访问数据的扫尾工作,包括关闭文件、释放内存、输出日志、清理数据等。 二、 析构方法语法 Python中所有类的析构方法都是特殊方法__del__,析构方法同样是一个实例方法,其语法如下: del(self) self就是对象自身,所有实例方法都有该参数,真正...

老猿Python 5257

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

IDEA的使用指南

IDEA基于java的使用手册,可以最快速的上手,在使用中不断的丰富自己的使用技巧.

QGraphicsScene执行clear时,QGraphicsScene内的图形对象会被析构吗

QGraphicsScene执行clear时,QGraphicsScene内的图形对象会被析构吗

xie__jin__cheng的博客 917

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

qt对象树析构详细顺序

,因为目标内存已经释放了,所以可能导致隐形的崩溃,问题是比较难查的了。了(其实压根父对象自己都别访问了,因为。

biao2488890051的博客 1201

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

子类析构时是否要调用父类的析构函数

转载自:子类析构时是否要调用父类的析构函数 descprition 构造时,先构造父类,再构造子类部分,因此父类和子类的构造函数都会被调用; 析构时,要分情况: (1)(父类析构函数不是虚函数)使用父类指针指向子类对象,析构该子类对象时,只会调用父类析构函数,因为不具多态性;(注意,这里的也就是说总共只调用一次析构,即父类析构,因为每个类的析构只调用一次),代码理解: class child:public parent{}; parent *p = new child(); delete p; //

ystraw - Come on!!! 4105

python类的析构方法是什么_第8.18节 Python类中内置析构方法__del__

一、引言基本上所有支持OOP设计的语言都支持析构方法(也称析构函数),析构方法都是在对象生命周期结束时调用,一般用来实施实例相关生命周期内访问数据的扫尾工作,包括关闭文件、释放内存、输出日志、清理数据等。二、析构方法语法Python中所有类的析构方法都是特殊方法__del__,析构方法同样是一个实例方法,其语法如下:del(self)self就是对象自身,所有实例方法都有该参数,真正调用时无需传递...

weixin_33330157的博客 1387

QGraphicsScene的函数,removeItem的对象,这个对象会被析构吗

QGraphicsScene的函数,removeItem的对象,这个对象会被析构吗

xie__jin__cheng的博客 1302

c++ --虚析构和纯虚析构

c++ --虚析构和纯虚析构 在c++中,我们知道在类内有些对象的成员需要在堆区创建空间,比如数组,其他类的对象做自己类的成员时需要创建空间,但是在调用多态中,需要父类指针或引用子类对象,那么在父类销毁指针时会调用父类的析构函数,那么子类的析构函数就不会被调用了,然后子类在堆区创建的空间就无法通过析构函数进行删除了,就会导致内存泄露,所以就要用虚析构或者纯虚析构来解决 语法 虚析构和纯虚析构的语法和虚函数与纯虚函数的语法相同 虚析构 virtual ~类名(){} 纯虚析构 virtual ~类名()=

Rejective的博客 316

深入探索 C++ 多态 ③ - 虚析构

前两章探索了 C++ 多态的虚函数调用链路和继承关系,本章将探索虚析构的工作原理。具有虚析构多态特征的类对象,被释放时:有继承关系的多态类,会先析构派生类,再析构基类,与它的构造顺序刚好相反。类的析构函数被调用时,对象的 this 指针和虚指针会在对应的类内部被重新设置,this 指针指向当前类对象对应的内存位置,虚指针也会被重置指向当前类对应的虚表。释放当前派生类对象内存。深入探索 C++ 多态 ① - 虚函数调用链路深入探索 C++ 多态 ② - 继承关系深入探索 C++ 多态 ③ - 虚析构。

wenfh2020的专栏 405

C++学习之多态-虚析构和纯虚析构

多态使用时,如果子类中有属性开辟到堆区,那么父类指针在释放时无法调用到子类的析构代码 解决方式:将父类中的析构函数改为虚析构或者纯虚析构 先看一个案例,子类在堆区开辟了空间: #include<iostream> #include<string> using namespace std; class animal { public: animal() { cout << "animal的构造函数" << endl; } virtual voi

阿乐的博客 470

关于c++静态成员变量析构的问题

是这样的,有一个类Map,它有一个static变量 还有一个static的函数 class Map { public: static void initMap(); private: static char *m_map; }; 在cpp文件中new了这个对象,问题来了,这个对象使用析构函数能析构掉吗? 我们来试试看 再加入一个getMap()函数; static char *getMap(); 然后new这个静态成员变量 char Map::m_map = new char[MAP_SIZEM

weixin_51965272的博客 3573

【资深架构师经验分享】:复杂对象析构时的调用顺序陷阱及避坑指南

掌握析构函数的调用顺序,避免资源泄漏与程序崩溃。本文详解C++复杂对象销毁时析构函数的调用顺序,涵盖继承、组合场景下的执行逻辑,提供可复用的设计模式与避坑策略,提升代码稳定性,值得收藏。

CodeWhim的博客 294
上一篇: carbide.vs调试技巧——缩减调试时间!
下一篇: carbide.vs的bug不断
misuo
博客等级 码龄22年 4粉丝 21原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值