从零开始学C++ (内存管理)

1.C/C++内存分布

C/C++中内存主要分为:栈、堆、数据段、代码段、内存映射段。

  1. 栈:又叫堆栈,存放非静态局部变量,函数的参数,返回值、栈是向下增长的。

  2. 堆:用于程序运行时动态分配。

  3. 数据段:存放全局变量,静态变量。

  4. 代码段:存放可执行的代码和常量。

  5. **内存映射段:**是高效的I/O映射方式,用于装载一个共享的动态内存库。用户可使用系统接口

    创建共享共享内存,做进程间通信。

2.C语言中动态内存管理方式

C语言中主要使用malloc,calloc,realloc和free来进行动态内存管理,那么malloc,calloc,realloc有什么区别呢?

1.函数原型与参数不同

  • malloc :void* malloc(size_t size);

    • 只接收1个 参数:要分配的总字节数。
  • calloc :void* calloc(size_t nmemb, size_t size);

    • 接收2个 参数:元素个数 和 单个元素大小 。实际分配的总字节数为 nmemb * size。
  • realloc :void* realloc(void *ptr, size_t new_size);

    • 接收2个 参数:原先的内存指针 和 新的总字节数。它用于调整已存在内存块的大小。

2.初始化行为不同

  • malloc :不会初始化 内存。分配的内存中存储的是残留的"脏数据"(随机值)。如果你需要清零,必须手动调用 memset。

  • calloc :会初始化为 0 。分配完成后,它会将内存块中的所有字节全部置为 0(保证数据安全)。

  • realloc :不会初始化新增的部分 。它只负责调整大小,原有的数据内容会被保留 (如果缩小,缩掉的部分丢失;如果扩大,新增加的空间不会清零,同样是脏数据)。

3.C++内存管理

C++使用new和delete来进行动态内存管理

1.new和delete用于内置类型

cpp 复制代码
	//动态申请一个int 类型的空间
	int* p1 = new int;
	//动态申请一个int 类型的空间并初始化为10
	int* p2 = new int(10);
	//动态申请是个int 类型的空间
	int* p3 = new int[10];

	delete p1;
	delete p2;
	delete[] p3;

注意,申请单个空间用new和delete,申请连续空间用new\[\]和delete\[\],要搭配使用。

2.new和delete用于自定义类型

cpp 复制代码
class A
{
public:
	A(int a = 0)
		: _a(a)
	{
		cout << "A():" << this << endl;
	}
	~A()
	{
		cout << "~A():" << this << endl;
	}
private:
		int _a;
};


int main() {

	//new和delete与malloc和free对内置类型的处理几乎没有区别,但对自定义类型,new和delete会调用构造函数和析构函数,malloc和free不调用
	A* p1 = (A*)malloc(sizeof(A));
	A* p2 = new A(10);

	free(p1);
	delete p2;

	int* p3 = (int*)malloc(sizeof(int)); // C
	int* p4 = new int;

	free(p3);
	delete p4;


	A* p5 = (A*)malloc(sizeof(A) * 10);
	A* p6 = new A[10];
	free(p5);
	delete[] p6;
	return 0;
}

4.operator new与operator delete****函数

new和delete操作符在底层实际上是调用operator new与operator delete两个全局函数,operator new也是通过malloc来申请空间,申请成功就直接返回,否则就执行用户提供的空间不足应对措施,如果用户提供就继续申请,否则就抛异常,operator delete通过free来释放空间。

5.new和delete的实现原理

1.内置类型

对于内置类型,new和delete与malloc和free基本类似,不同在于new和delete申请和释放的是单个空间,new\[\]和delete\[\]申请和释放的是连续空间,new申请失败会抛异常,malloc申请失败会返回NULL。

2.自定义类型

new和delete

new:

  1. 调用operator new完成空间的申请
  2. 调用构造函数,完成对对象的初始化构造

delete:

  1. 调用析构函数,完成对对象资源空间的清理
  2. 调用operator delete完成空间的释放

new\[\]和delete\[\]

new\[\]:

  1. 调用operator new\[\],实际上operator new\[\]调用operator new完成N次空间的申请
  2. 调用N次构造函数,完成对对象的初始化构造

delete\[\]:

  1. 调用N次析构函数,完成对对象资源空间的清理
  2. 调用operator delete\[\],operator delete\[\]调用operator delete完成N次空间的释放
相关推荐
aqiu11111114 小时前
【C++算法打怪专栏】LeetCode 165. 比较版本号(双指针与字符串流法)
c++·算法·leetcode
Joy T14 小时前
Spring AI 接入已有 Java 项目的三种架构设计
java·人工智能·springai·ai入门·chatclient·ai service·ai能力接入
chenbingjie_c15 小时前
C++ STL 适配器:stack & queue,从 vector/list 到 deque 深度解析
数据结构·c++
杨运交15 小时前
[076][核心模块]构建优雅的Java异常处理框架:从错误码到全局异常处理
java·开发语言
caoerzhong15 小时前
仓库数字化成熟度分级:JeeWMS 开源 Java 仓库管理系统如何支撑从可见到自治的四级跃迁
java·开源
MayBaymax15 小时前
RocketMQ 存储机制
java·rocketmq
程序猿_极客15 小时前
【免费】分享一套优质的基于SpringBoot的服装商城管理系统的设计与实现(带可视化图表、协同过滤功能),源码+文档+视频详解(讲解)
java·spring boot·后端·服装商城管理系统
用户37215742613515 小时前
Java 查找并高亮 Word 文字:精确查找及正则表达式模糊查找
java
zyseo816 小时前
谷歌SEO 站内搜索优化实战:把站内搜索词变成关键词金矿
java·服务器·数据库
bug菌16 小时前
🤔同事突然问我:Spring的注解 @Component 和 @Service 有何不同?
java·spring boot·后端