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

C++动态内存管理 模板

动态内存管理

C++内存分区

C++程序的内存通常划分为五个主要区域,每个区域有特定用途和管理方式:

代码区(Text Segment)

  • 存放程序的机器指令,即编译后的可执行代码

  • 通常是只读的,防止指令被意外修改

  • 多个相同程序的进程可共享此区域,节省内存

栈区(Stack)

  • 存储局部变量(非static修饰)、函数参数、返回地址等

  • 由编译器自动管理内存,遵循“后进先出”(LIFO)原则

  • 内存分配和释放速度快,但空间有限(通常1MB到8MB),超出会导致栈溢出

  • 每次进入一个函数就建立一个新的栈

堆区(Heap)

  • 通过newmalloc动态分配内存,需手动释放(deletefree)

  • 生命周期由开发者控制,未释放会导致内存泄漏

  • 空间较大,但管理复杂,访问速度较栈区慢

全局/静态存储区(Global/Static Storage Area)

  • 存放全局变量、静态变量(static修饰)

  • 分为已初始化(Data段)和未初始化(BSS段)两部分

  • 生命周期为整个程序运行期间,编译时分配内存并初始化

常量存储区(Constant Storage Area)

  • 存放常量值,如字符串常量、const修饰的全局常量

  • 内存区域不可修改,防止数据被意外更改

  • 生命周期与程序相同,通常位于只读数据段

  • const不改变存储的地址,被const修饰的变量或函数并不属于常量区


new和delete操作符

C++通过new和delete操作符进行动态内存管理,示例如下
void Test() { // 动态申请一个int类型的空间并默认初始化成0 int* ptr4 = new int; // 动态申请一个int类型的空间并初始化为10 int* ptr5 = new int(10); // 动态申请10个int类型的空间并默认初始化成0 int* ptr6 = new int[10]; // 动态申请10个int类型的空间并初始化 int* ptr7 = new int[10]{1,2,3,4,5,6,7,8,9,10}; //释放申请的空间 delete ptr4; delete ptr5; delete[] ptr6;//注意这里的释放带[] }

operator new与operator delete函数

new和delete是用户进行动态内存申请和释放的操作符,而operator new 和operator delete是系统提供的全局函数new在底层调用operator new全局函数来申请空间,delete在底层通过operator delete全局函数来释放空间,operator new/operator delete和new/delete以及malloc/free的关系如下:

new的原理

1. 调用operator new函数申请空间,而operator new又是通过调用c语言的malloc来申请空间

2. 在申请的空间上执行构造函数,完成对象的构造

delete的原理

1. 在空间上执行析构函数,完成对象中资源的清理工作

2. 调用operator delete函数释放对象的空间,operator delete则是调用了


malloc/free和new/delete的区别

malloc/free和new/delete的共同点是:都是从堆上申请空间,并且需要用户手动释放。不同的地方如下:

1. malloc和free是函数,new和delete是操作符

2. malloc申请的空间不会初始化,new可以初始化

3. malloc申请空间时,需要手动计算空间大小并传递,new只需在其后跟上空间的类型即可, 如果是多个对象,[]中指定对象个数即可

4. malloc的返回值为void*, 在使用时必须强转,new不需要,因为new后跟的是空间的类型

5. malloc申请空间失败时,返回的是NULL,因此使用时必须判空,new不需要,但是new需要捕获异常

6. 申请自定义类型对象时,malloc/free只会开辟空间,不会调用构造函数与析构函数,而new在申请空间后会调用构造函数完成对象的初始化,delete在释放空间前会调用析构函数完成空间中资源的清理(最大的区别)


模板

函数模板

函数模板代表了一个函数家族,该函数模板与类型无关,在使用时被参数化,根据实参类型产生函数的特定类型版本

函数模板格式:

template<typename T1, typename T2,......,typename Tn>

(返回值类型 函数名(参数列表){})

template<typename T>//typename也可以写成class没有影响 void Swap( T& left, T& right) { T temp = left; left = right; right = temp; }//这里的T就是不定的类型

函数模板的实例化

用不同类型的参数使用函数模板时,称为函数模板的实例化。模板参数实例化分为:隐式实例化和显式实例化。

隐式实例化:编译器根据参数类型自动推导T的类型(注意,只能根据实参的类型而不是返回值)

显式实例化:显式实例化:在函数名后的<>中指定模板参数的实际类型,一般更多的情况下使用隐式实例化,显式实例化在下面的情况下可以使用

template<class T> T Add(const T& left, const T& right) { return left + right; } int main() { int a1 = 10, a2 = 20; double d1 = 10.0, d2 = 20.0; Add(a1, d2); /* 该语句不能通过编译,当编译器看到该实例化时 通过实参a1将T推演为int,通过实参d1将T推演为double类型,但模板参数列表中只有一个T, 编译器无法确定此处到底该将T确定为int 或者 double类型而报错 注意:在推导时,编译器一般不会进行类型转换操作 */ // 此时有两种处理方式:1. 用户自己来强制转化 2. 使用显式实例化 Add(a1, (int)d1); Add<int>(a1, d1);//一开始就将T定为int return 0; }

也可以选择模板中设立多个参数解决这个问题(即仍然采用隐式实例化的方式解决)

template<class T1, class T2> T2 Add(const T1& left, const T2& right) { return left + right; } int main() { int a1 = 10, a2 = 20; double d1 = 10.0, d2 = 20.0; cout<<Add(a1, d2);//此时T1判定为int,T2判定为double(返回值就是double) return 0; }

类模板

类模板的定义格式如下:

template<class T> class fukes{ public: fukes(T a,T b):_a(a),_b(b){} void reverses(T a, T b); private: T _a; T _b; }; template<class T>//在类模板中声明和定义不宜轻易分离,因为在定义前需另外加上T的匹配 void fukes<T>::reverses(T a,T b) {//可以理解为不这么写类模板外就不知道T是什么 std::swap(a, b); } int main() { fukes<int> k(10, 20); return 0; }

类模板的实例化

类模板实例化与函数模板实例化不同,类模板实例化需要在类模板名字后跟<>,然后将实例化的类型放在<> 中即可,类模板名字不是真正的类,而实例化的结果才是真正的类,如vector才是真正的类名,vector<int>才是类型

http://www.rkmt.cn/news/1495708.html

相关文章:

  • 工厂用吸尘器排行榜2025实测:史沃斯凭什么稳居第一? - 工业清洁测评社
  • 【安装】RocketMQ
  • 5分钟上手YimMenu:GTA5终极免费防护与增强工具完全指南
  • SSL Socket 通信与本地 Mock Server 实践指南
  • 影刀RPA新手入门完全指南
  • 2026上海触点润滑脂十大供应商实力榜:六家高精度导电脂技术标杆企业的差异化优势深度解析 - 品牌发掘
  • @username 的推文
  • 2026广州白云区搬家公司综合实力TOP5排行榜:服务、价格与售后全维度评测 - 从来都是英雄出少年
  • ansys 求解过程中出现未知错误。检查“求解信息”对象上的“求解器输出”,查找可能的原因。-静力学分析遇到的,这是什么原因——An unknown error occurred ——未找到解决方法
  • 从MySQL到云原生:全面解析阿里云PolarDB数据库及其与MySQL的核心差异
  • 2026食材配送服务商口碑优选榜:六家稳扎稳打的本土供应品牌,从品控溯源到智慧物流的核心实力深度解析 - 品牌发掘
  • 动态随机一般均衡建模终极指南:40+实战模型快速掌握
  • CodeIsland故障排除:10个常见问题与终极解决方案大全
  • QuickLook.Plugin.OfficeViewer-Native:如何通过原生Office组件实现秒级文档预览
  • i.MX RT1015电气特性与接口时序实战解析:从数据手册到硬件设计
  • 2026国内草酸连续冷却结晶器供应商口碑推荐榜:六家技术领军品牌的工艺优势与市场地位深度解析 - 品牌发掘
  • Amoeba:Ruby on Rails中ActiveRecord对象复制的终极指南
  • 2026年6月广州搬家公司全维度测评:如何避开陷阱选对靠谱搬家品牌更省心? - 生活服务
  • 3步构建个人游戏云:Sunshine开源串流服务器实战指南
  • 广州厂房搬迁服务:大型工厂搬厂专业搬迁团队、全车型调度与资质核验指南 - 从来都是英雄出少年
  • 不锈钢卫浴柜技术解析与靠谱厂家实测参考 - 起跑123
  • 寄快递哪个平台最便宜?2026寄件渠道5折起实测对比 - 快递物流资讯
  • 本科毕设可用的网络流量分类Python项目:含训练好的CNN/VGG模型、论文文档和答辩PPT
  • AC:100
  • 瑜伽服面料科技——AI加速创新材料研发
  • 7个关键策略优化Kronos金融预测模型:从基础应用到生产部署
  • 做小程序的公司有哪些?常见公司类型和适用场景梳理
  • 2026广州别墅搬家精选:全屋高端精品打包、无损搬运全流程服务评测 - 从来都是英雄出少年
  • 3分钟搞定视频字幕:VideoSrt Windows GUI工具完整指南
  • 2026成都菁英单招|免费第一课试学的官方联系方式,先体验再报名,择校不踩坑✅ - 成都单招培训