当前位置: 首页 > news >正文

10类外的动态内存

1类外堆内存

1.1基本概念

当类对象拥有指针或引用,指向从malloc()、new等操作符所分配的额外堆内存时,这些内存称为类外堆内存。
类对象 ——>堆内存
类外堆内存的特点,除非手动调用free(),delete()等释放内存的手段,否则这些内存单元不会随着类对象的释放而自动释放。实际上、类外堆内存是导致程序内存泄露的一个大原因,并由此产生了一众所谓智能指针的机制,这在STL库中会有所探究。

1.2默认情况下的内存泄露

如上图所示,类对象本身在变量声明周期结束时会被系统自动释放,但是堆内存不会。
以下示例代码展示了未正确编写析构函数时产生的内存泄漏的典型情形:
class A{
char *p;
public://分配1000个字节
A(){p=new char[100];}
~A(){cout<<"析构"<<endl};
};
int main(int argc,char cosnt *argv[]){
A a;
return 0;
}
可以看出,虽然程序正确执行了析构函数,但由于析构函数并未正确释放指针p所指向的堆内存导致该程序泄露了1000个字节的系统内存。

1.3析构函数正确释放内存

从上述示例代码中容易得到结结论:只要类中分配有类外堆内存,就必须重写析构函数并在其中加以释放,否则会导致内存泄露。
以下是正确的使用析构函数释放类外堆内存的一个简单示例:
class A{
char *p;
public : //分配1000个字节
A(){p = new char[1000];}
~A(){cout <<"析构"<<endl;delete[] p;}
};
int main(int argc,char const *argv[]){
A a;
return 0;
}
注意:针对不同的分配的方式,析构函数也必须要用相应的方式去释放,比如:
构造函数中使用malloc()//calloc()f分配内存,析构函数必须使用free()释放内存
构造函数中使用new分配内存、析构函数必须使用delete释放内存
构造函数中使用new[]分配内存,析构函数必须使用deletep[]释放内存

2继承关系中的动态内存管理

假设基类Base,使用了动态内存:
class Base{char data ;指向类外动态内存
int size;
public : //构造函数
Base(const char
data = "null",int size = 0);
Base(const Base &r);
//赋值操作符函数
Base &operator = (const Base &r);
//虚析构函数
//此处可暂且不管其含义,只需要假设它负责妥善释放基类资源
virtual ~Base();
}
此处,由于基类Base使用了动态内存,因此基类的构造函数和析构函数都将会有显式定义来应对动态内存的管理。
这是,当基类派生出子类后,注意考虑两方面问题:
1.子类对象在拷贝构造,赋值操作时,如何正确处理基类相关的动态内存?
2.子类对象在析构时,如何正确处理基类相关的动态内存?
以上2个问题,又可以分别细分讨论两种情形:
子类没有使用动态内存
字母有使用动态内存

2.1子类没有使用动态内存

现在,从基类Base派生子类Derived如下:
class Derived:public Base{
//假设派生类Derived没有使用动态内存
}
此种情形是非常简单的,有如下图所示“
派生类(基类)——>(管理)堆内存
因此此时子类没有使用动态内存,所有子类就无需对构造函数、析构函数和赋值操作符函数等做显式定义,而派生类的无所作为的行为不会对基类的动态内存管理造成任何问题,理由是:
构造函数、拷贝构造函数、赋值运算符函数:
子类对象在默认的上述函数中都会自动调用基类的版本、因此无需做任何额外的处理。
析构函数:
派生类对象在执行完析构函数后,会自动调用基类的析构函数(包括在默认生成的空析构函数),因此也无需做任何额外的处理。

2.1.1最终的结论

只要基类Base本身设计妥当,那么对于不带动态内存的派生类而言,其设计无需考虑任何基类的动态内存的问题。
class Derived:public Base{
//无需对构造、拷贝构造、赋值操作符、构造等类方法
做额外的处理
};

http://www.jsqmd.com/news/1169624/

相关文章:

  • 2026商用清洁机器人品牌调研:五大主流品牌横向解析,覆盖全场景清洁需求 - 匠言榜单
  • MAX11108A与MKV58F1M0VLQ24的高精度ADC系统设计
  • 开发者必读:CyclOne平台二次开发与API集成指南
  • LDSC终极指南:5步掌握遗传力分析与基因组数据解构技术
  • Claude 3.5 Sonnet实测:Python脚本与SQL调试提效实践
  • SAP MM 采购组织3种模式对比:集中采购与分散采购的5个关键决策点
  • 太原小众宴席场地测评|平价生日宴升学宴聚餐优选 - 资讯快报
  • GLM5.1如何实现UEFI裸金属游戏开发
  • Gemma 4国产安卓手机离线部署全指南
  • GPT充值升级 Pro 前先避坑:别把版本、Codex 和 API 搞混
  • WaveTools鸣潮工具箱:一站式游戏优化与抽卡管理神器
  • A3908驱动芯片与PIC18F86J55在精密运动控制中的应用
  • 会话内存泄漏预警,深度解析Claude Code 3.5中WebSocket连接池与上下文缓存的隐式耦合风险
  • GPTs推荐清单泄露:Top 5生产力增强型GPTs已通过API调用压测验证(QPS≥8.2,响应<1.3s)
  • SpringBoot 2.x 集成宝兰德中间件 9.5.2:5步完成Tomcat替换与WAR包部署
  • 2026年7月最新济南宝玑官方售后客服服务电话及地址网点大全 - 亨得利钟表维修中心
  • DeepSeek准确率卡在91%再也上不去?20年NLP老兵拆解模型-数据-服务三层耦合陷阱,今晚24点前失效的调优清单
  • AssetRipper实战指南:Unity游戏资源提取与项目重构全流程
  • 上海华凌冰箱(WAHIN)售后服务24小时热线 - 资讯快报
  • 2026年线上展厅制作公司实力排行
  • LL(1) 文法实战:3步构建预测分析表,解决王原生习题4.1歧义
  • openEuler HA-web与HA-API集成部署指南:构建完整的高可用集群解决方案
  • PKSM终极指南:如何在3DS上轻松管理全世代宝可梦存档
  • 锂电池组主动平衡方案:BQ25887与MKV46F256VLH16应用
  • 2026 年东昌专业的聚酰胺固化剂回收厂商怎么联系,扔掉它?揭秘聚酰胺固化剂的惊人回收价值 - 企业信息推荐【官方】
  • Zemax 公差分析:5个常见设置误区与补偿器(COMP)的正确使用指南
  • AI程序员崛起真相:2024年真实招聘数据揭示——78%企业已调整技术岗JD,你还在写CRUD?
  • 华硕笔记本终极自定义指南:用G-Helper解锁AniMe Matrix矩阵屏全部潜力
  • 终极指南:如何用免费开源插件Video Speed Controller掌控视频播放速度
  • 无局放谐振装置现场组装与普通装置的差异(一)