【C++】内存管理

文章目录

  • 一、C++内存区域划分
  • 二、C++内存管理方式
    • 1. new / delete 操作内置类型
    • 2. new / delete 操作自定义类型
    • 3. new / delete 的实现原理
    • 4. malloc / free 和 new / delete 的区别
  • 三、placement new(了解)

一、C++内存区域划分

栈:又叫堆栈,用于建立函数栈帧,一般向下增长,高地址到低地址

堆:用于程序运行时的动态内存分配,一般向上增长,低地址到高地址

数据段:也叫静态区,存放全局变量和静态变量

代码段:也叫常量区,存放代码和常量

二、C++内存管理方式

C++ 通过 new 操作符和 delete 操作符进行动态内存管理。

1. new / delete 操作内置类型

申请和释放单个元素的空间:用 new 和 delete

例子:

// 动态申请一个int类型的空间
int* ptr1 = new int;

// 动态申请一个int类型的空间并初始化为10
int* ptr2 = new int(10);

delete ptr1;
delete ptr2;

申请和释放连续空间:用 new T[N] 和 delete[]
注意要匹配起来使用,否则结果是未定义的。

例子:

// 动态申请10个int类型的空间
int* ptr3 = new int[3];

// 动态申请10个int类型的空间并初始化
int* ptr4 = new int[3]{1, 2, 3};

delete[] ptr3;
delete[] ptr4;

2. new / delete 操作自定义类型

new 操作自定义类型:开辟空间 + 调用构造函数

delete 操作自定义类型:调用析构函数 + 释放空间

3. new / delete 的实现原理

new 和 delete 是我们用来动态管理内存的操作符。

new 在底层会调用 operator new 函数,该函数是系统提供的一个全局函数。而 operator new 函数又会调用 malloc 函数来开辟内存,如果申请成功则直接返回,如果申请失败则抛出异常。
delete 在底层会调用 operator delete 函数,该函数也是系统提供的一个全局函数。而 operator delete 函数又会调用 free 函数来释放空间。

所以 new 其实是先调用 operator new 函数来开辟空间,再调用构造函数来初始化对象。如果开辟连续 N 个的空间,就调用 N 次这两个函数。
同理,delete 就是先调用析构函数来清理资源,再调用 operator delete 函数来释放空间。如果释放连续 N 个的空间,就调用 N 次这两个函数。

4. malloc / free 和 new / delete 的区别

malloc / free 和 new / delete 都是从堆上申请空间,并且需要手动释放。
但是 malloc / free 是函数,new / delete 是操作符。

从用法上来说,new 申请空间的同时可以初始化,malloc 不可以;而且 malloc 要手动计算申请空间的大小并传递,返回值必须手动强转。所以 new 使用起来会简洁很多。

另外,malloc 申请失败会返回空指针,使用时需要判空;而 new 申请失败会抛出异常,使用时需要捕获异常。

底层上,malloc 和 free 只是申请和释放空间,而 new 和 delete 还封装了调用构造函数初始化和调用析构函数清理资源的功能。

三、placement new(了解)

placement new 就是在已分配的原始内存空间中调用构造函数初始化一个对象。

使用方式:
new (place_address) type
或者 new (place_address) type(initializer-list)

使用场景:
placement new 一般是配合内存池使用。
因为内存池分配出的内存没有初始化,对于自定义类型的对象需要显式调用构造函数来初始化,而构造函数刚好可以通过 placement new 来显式调用。

例子:

int main()
{
	//eg.1
	A* p1 = (A*)malloc(sizeof(A));//申请空间
	new(p1)A;//通过placement new显式调用构造函数
	p1->~A();//析构函数可以直接显式调用
	free(p1);//释放空间

	//eg.2 同理
	A* p2 = (A*)operator new(sizeof(A));
	new(p2)A(10);
	p2->~A();
	operator delete(p2);
}

你可能感兴趣的:(#,C++入门,c++,开发语言)