C++动态内存管理

来源:互联网 发布:淘宝美工和室内设计师 编辑:程序博客网 时间:2024/05/29 16:59

1.C的动态内存管理细节

C语言使用malloc/calloc/realloc/free进行动态内存管理。

且需要成对使用,开辟空间使用完之后一定要free掉。

其中,malloc和realloc都是开辟一块空间,返回这块空间的起始地址。但二者有区别,malloc开辟空间返回首地址,realloc开辟空间,并且初始化这块儿空间,然后返回这块空间的首地址。

2.C动态管理在C++中的缺陷引入C++动态内存管理

在C语言中动态内存管理时存在一些缺陷。C语言中开辟空间使用完后只是简单的free掉,而C++中,使用new开辟空间,若为简单内置类型时,和C语言中几乎相同,而若为自定义类型时,开辟空间的同时并且要调用构造函数进行初始化,在delete时调用析构函数进行清理成员。

【malloc/free和new/delete的区别和联系?】
1. 它们都是动态管理内存的⼊⼜。
2. malloc/free是C/C++标准库的函数,new/delete是C++操作符。
3. malloc/free只是动态分配内存空间/释放空间。⽽new/delete除了分配空间还会
调⽤构造函数和析构函数进⾏初始化与清理(清理成员)。
4. malloc/free需要⼿动计算类型⼤⼩且返回值会void*,new/delete可⾃⼰计算类
型的⼤⼩,返回对应类型的指针。

3.C++动态内存管理基本语法和使用

new/delete动态管理对象。
new[]/delete[]动态管理对象数组。

new和delete需成对使用,例如:


4.C++提供的动态内存管理的底层实现及其接口operator new/delete/new[]/delete[]

C++的其他内存管理接⼜(placement版本)
void * operator new (size_t size);
void operator delete (void* p);
void * operator new [](size_t size);
void operator delete[] (void* p);
总结:
1. operator new/operator delete operator new[]/operator delete[] 和 malloc/free⽤法⼀样。
2. 他们只负责分配空间/释放空间,不会调⽤对象构造函数/析构函数来初始化/清理对
象。
3. 实际operator new和operator delete只是malloc和free的⼀层封装。

new做了两件事
1. 调⽤operator new分配空间。
2. 调⽤构造函数初始化对象。
delete也做了两件事
1. 调⽤析构函数清理对象
2. 调⽤operator delete释放空间
new[N]
1. 调⽤operator new分配空间。
2. 调⽤N次构造函数分别初始化每个对象。
delete[]
1. 调⽤N次析构函数清理对象。
2. 调⽤operator delete释放空间。

5.定位new表达式

定位new表达式是在已分配的原始内存空间中调⽤构造函数初始化⼀个对象。
new (place_address) type
new (place_address) type(initializer-list)
place_address必须是⼀个指针,initializer-list是类型的初始化列表。

#include <iostream>using namespace std;class Array{public:Array(size_t size = 10): _size(size), _a(0){cout << "Array(size_t size)" << endl;if (_size > 0){_a = new int[size];}}~Array(){cout << "~Array()" << endl;if (_a){delete[] _a;_a = 0;_size = 0;}}private:int* _a;size_t _size;};void test(){// 1.malloc/free + 定位操作符new()/显⽰调⽤析构函数,模拟 new和delete 的⾏为Array* p1 = (Array*)malloc(sizeof(Array));new(p1) Array(100);p1->~Array();free(p1);// 1.malloc/free + 多次调⽤定位操作符new()/显⽰调⽤析构函数,模拟 new[]和delete[]//的⾏为Array* p2 = (Array*)malloc(sizeof(Array) * 10);for (int i = 0; i < 10; ++i){new(p2 + i) Array;}for (int i = 0; i < 10; ++i){p2[i].~Array();}free(p2);}int main(){test();return 0;}

运行结果如下:


6.delete[] 析构函数调用细节剖析

(1)new 首先调用operator new(),再调用malloc(),再调用构造函数,最后返回空间首地址。

(2)delete 首先调用析构函数,再调用operator delete(),最后free。

(3)new[] 显示定义析构函数时,会多开4个字节存储对象个数。首先调用operator new[],进而调用operator new(),malloc,构造函数(count次),返回首地址。

(4)delete[] 调用析构函数(count次),再调用operator delete[],operator delete(),最后free。

具体过程如下图所示: