0%

C++中基本的内存管理

C/C++内存分布

  1. 栈:非静态局部变量,函数参数,返回值等,栈是向下增长的
  2. 内存映射段:装载一个共享的动态内存库
  3. 堆:用于程序运行时动态内存分配,可以向上增长
  4. 数据段:存储全局变量和静态数据
  5. 代码段:可执行的代码、只读常量

C语言中内存管理方式

malloc(申请空间)、calloc(申请空间并进行零初始化)、realloc(调整空间大小,原地调整大小或重开空间,拷贝内容,释放原空间)

free(释放空间)

C++内存管理

new / delete 操作内置类型

申请空间:

1
2
3
int* ptr1 = new int;//动态申请一个int类型的空间
int* ptr2 = new int(10);//动态申请一个int类型的空间并初始化为10
int* ptr3 = new[10];//动态申请10个int类型的空间
  • 单个类型的空间:new + 类型

  • 连续空间:new + 类型[个数]

  • 单个类型空间申请 + 初始化:new + 类型(初始值)

释放空间:

1
2
3
delete ptr1;
delete ptr2;
delete[] ptr3;
  • 单个空间delete 指针
  • 连续空间:delete[ ] 指针

new / delete操作自定义类型

动态创建自定义类型的对象:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Date
{
public:
Date(int year)
{
_year = year;
}
private:
int _year;
};

void test()
{//new:动态开空间 + 调用构造函数初始化
Date* pd1 = new Date(2020);
Date* pd2 = new Date(2019);//调用默认构造:无参构造,全缺省构造
Date* pd3 = new Date[10];
}
  • 申请单个空间:new 自定义类型(参数列表),调用构造函数初始化
  • 申请连续空间:new 自定义类型[个数] , 自动调用默认构造进行初始化,如果没有则编译器报错

释放自定义类型的空间:

1
2
3
delete pd1;//调用一次析构 + 释放空间
delete pd2;//调用一次析构 + 释放空间
delete[] pd3;//调用十次析构,因为Date[10] + 释放空间
  • 调用析构函数清理资源 + 释放空间

operator new 与 operator delete函数

1
void* operator new(size_t n)
  • 不是运算符重载函数,而是一个全局函数

  • 使用方式和malloc类似

  • 封装malloc + 异常处理机制

申请失败会抛出bad_alloc类型异常

执行过程:operator new --> malloc --> 构造函数

1
void operator delete(void* ptr)
  • 不是运算符重载函数
  • 使用方式和free类似
  • 封装free

_只有自定义类型才会调用构造函数和析构函数_

operator new 与 operator delete的类专属重载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
struct Node
{
public:
Node()
{
cout << "Node()" << endl;
}
void operator new(int data)
{
void* p = nullptr;
p = allocator<Node>().allocate(1);
cout << "mem pool allocate" << endl;
return p;
}
void operator delete(Node* ptr)
{
allocator<Node>().deallocate((Node*)ptr, 1);
cout << "mem pool deallocate" << endl;
}
private:
int _data;
Node* _next;
};

void test()
{
Node* np1 = new Node;
Node* np2 = new Node[10];

delete np1;
delete[] np2;
}

new / delete 原理

内置类型:

  • new : operator new --> malloc 失败抛异常

  • delete : operator delete --> free

  • new [] : operator new[] --> operator new --> malloc

  • delete [] : operator delete[] – > operator delete --> free

  • 和malloc区别:new空间申请失败抛异常,malloc空间申请失败返回空指针

  • 和free区别:没有本质区别,delete封装了free操作

自定义类型:

  • new : operator new --> malloc --> 构造函数 失败抛异常

  • delete : 析构函数 --> operator delete --> free

  • new [] : operator new[] --> operator new --> malloc --> N此构造函数

  • delete [] : N次析构函数 --> operator delete[] – > operator delete --> free

  • 和malloc区别:new空间申请失败抛异常,malloc空间申请失败返回空指针,new会调用自定义类型的构造函数,完成初始化,malloc不会

  • 和free区别:delete会调用自定义类型的析构函数,完成资源清理的工作,free不会

new定位表达式:new(地址)类型(参数列表)

:在已经开好的空间上显示调用构造函数

new(pd)Date(2030);

1
2
3
4
Date* pd = (Date*)malloc(sizeof(Date));
new (pd)Date(2030);
Date* pd2 = (Date*)malloc(sizeof(Date));
new (pd2)Date;
-------------本文结束感谢您的阅读-------------