> 文档中心 > C/C++内存管理

C/C++内存管理

目录

1. 首先做一道题

2. C/C++的内存管理方式

2.1 概念

2.2 malloc,new的区别,free,delete的区别

2.3 抛异常的捕获(后面会讲)

2.4 operator new与operator delete函数

2.5 operator new[]

2.6 new delete不匹配问题

3. new和delete 的总结 

3.1 内置类型

3.2 自定义类型

4. 池化技术&&定位new表达式(placement-new) 


C语言总结在这常见八大排序在这

作者和朋友建立的社区:非科班转码社区-CSDN社区云💖💛💙

期待hxd的支持哈🎉 🎉 🎉

最后是打鸡血环节:你只管努力,剩下的交给天意🚀 🚀 🚀  

1. 首先做一道题

测试一下自己哈,实在不懂可以评论区或者私聊哈

 答案(做的时候没反应过来全局变量是静态区哈哈)

【说明】

1. 又叫堆栈,非静态局部变量 / 函数参数 / 返回值等等,栈是向下增长的。 2. 内存映射段 是高效的 I/O 映射方式,用于装载一个共享的动态内存库。用户可使用系统接口创建共享共享内存,做进程间通信。(Linux 课程如果没学到这块,现在只需要了解一下) 3. 用于程序运行时动态内存分配,堆是可以上增长的。 4. 数据段 -- 存储全局数据和静态数据。 5. 代码段 -- 可执行的代码 / 只读常量。  

2. C/C++的内存管理方式

2.1 概念

我们知道C是malloc/calloc/realloc。

C 语言内存管理方式在 C++ 中可以继续使用,但有些地方就无能为力而且使用起来比较麻烦,因此 C++ 又提出了自己的内存管理方式:通过 new delete 操作符进行动态内存管理 例如:

C++11:

注意:申请和释放单个元素的空间,使用 new delete 操作符,申请和释放连续的空间,使用 new[] delete[]

2.2 malloc,new的区别,free,delete的区别

在申请自定义类型的空间时,new会调用构造函数,delete会调用析构函数,而malloc与free不会。其他的没有本质的区别。

2.3 抛异常的捕获(后面会讲)

 也就是这个原因,所以new不用想malloc一样去判断

2.4 operator newoperator delete函数

首先operator new operator delete是两个库函数不是new delete的重载(malloc free是函数 new delete 是操作符),这也是很容易引起误会的地方。

new delete 是用户进行 动态内存申请和释放的操作符 operator new operator delete 是系统提供的 全局函数 new 在底层调用 operator new 全局函数来申请空间, delete 在底层通过 operator delete 全局 函数来释放空间。

operator new 的本质是封装了malloc,但是失败不返回空,是抛异常(可以去看对应的源码)
operator delete 本质也是封装的free(为了和operator new 配对)

operator new && malloc

那还不如 new 好用
所以operator new 是没有直接价值的,但是有间接价值:
call operator new call 构造函数

new的本质其实是call operator new 和 call Stack的构造函数

2.5 operator new[]

不过其实operator new[] 也是封装的operator new 

 

2.6 new delete不匹配问题

虽然都没有正确匹配使用delete,但是上面不报错下面报错,简单提一下原因(不全),上面还是相当于malloc 然后 free 所以没问题,下面是相当于new10 只delete 1次,不过还有很多底层机制的问题 

3. newdelete 的总结 

3.1 内置类型

如果申请的是内置类型的空间, new malloc delete free 基本类似,不同的地方是: new/delete 申请和释放的是单个元素的空间,new[] delete[] 申请的是连续空间,而且 new 在申请空间失败时会抛异常, malloc 会返回 NULL

3.2 自定义类型

new 的原理 1. 调用 operator new 函数申请空间 2. 在申请的空间上执行构造函数,完成对象的构造 delete 的原理 1. 在空间上执行析构函数,完成对象中资源的清理工作 2. 调用operator delete函数释放对象的空间 new T[N] 的原理 1. 调用 operator new[] 函数,在 operator new[] 中实际调用 operator new 函数完成 N 个对象空间的申请 2. 在申请的空间上执行 N 次构造函数 delete[] 的原理 1. 在释放的对象空间上执行 N 次析构函数,完成 N 个对象中资源的清理 2. 调用 operator delete[] 释放空间,实际在 operator delete[] 中调用 operator delete 来释放空间

4. 池化技术&&定位new表达式(placement-new) 

//以下内容后面会详细说,先了解

在连续多次申请空间的时候,效率是低下的

池化技术可以解决(内存池,进程池)
就是开辟一块大的空间然后以后去内存池申请和释放空间,可以这么理解,内存池离我们进,速度快

我们上面开始提到了,new会去调用operator new,但是这是全局的(库里面的),现在我们去重载一个operator new,就会去调用这个专属的(内存池)
我们new的是Listnode 所以我们就在Listnode里面写一个operator new / delete

意义就是提高效率 

假设现在我们有了一块空间并且没有初始化,我们如何 显示调用构造函数去初始化呢(平时都是编译器默认调用的,我们自己是不能直接调用的)? 定位new表达式: 定位 new 表达式是在 已分配的原始内存空间中调用构造函数初始化一个对象 使用格式: new (place_address) type 或者 new (place_address) type(initializer-list) place_address 必须是一个指针, initializer-list 是类型的初始化列表 使用场景: 定位 new 表达式在实际中一般是配合内存池使用。因为内存池分配出的内存没有初始化,所以如果是自定义类型的对象,需要使用new 的定义表达式进行显示调构造函数进行初始化。

意义:内存池切出来的内存就要用定位new

最后的最后,创作不易,希望读者三连支持💖

赠人玫瑰,手有余香💖