

声明:以下知识相关资料来自比特官网和小编手搓~
C/C++内存管理++1、C/C++内存分布++
++2、C语言中动态内存管理方式:malloc/calloc/realloc/free++
++3、C++内存管理方式++
3.1、new/delete操作内置类型
3.2、new和delete操作自定义类型
++4、operator new 与 operator delete 函数++
++5、new 和 delete 的实现原理++
5.1、内置类型
5.2、自定义类型
++6、定位new表达式(placement-new)++
++7、malloc/free 和 new/delete 的区别++
1、C/C++内存分布
C语言和C++的内存划分是一样的,常见内存区域就是:栈区、堆区、静态区、常量区,现在推出命名更加官方的区域划分:静态区 -> 数据段;常量区 -> 代码段。
栈区:函数栈帧的创建,其空间就是在栈上申请的,常见的局部变量也在这,及时申请、销毁,还有函数参数、返回值等等。
堆区:当数据结构存储数据空间不够时,额外申请的空间都是在堆区上申请开辟的,这个区域是给操作者发挥的区域。
给点题目试试水:
cppint globalVar = 1; static int staticGlobalVar = 1; void Test() { static int staticVar = 1; int localVar = 1; int num1[10] = { 1, 2, 3, 4 }; char char2[] = "abcd"; const char* pChar3 = "abcd"; int* ptr1 = (int*)malloc(sizeof(int) * 4); int* ptr2 = (int*)calloc(4, sizeof(int)); int* ptr3 = (int*)realloc(ptr2, sizeof(int) * 4); free(ptr1); free(ptr3); }
2、C语言中动态内存管理方式:malloc/calloc/realloc/free
*3、*C++内存管理方式
C++这里用独有的 new 和 delete 操作符进行内存管理。
3.1、new/delete操作内置类型
cppvoid Test() { // 动态申请一个int类型的空间 int* ptr4 = new int; // 动态申请一个int类型的空间并初始化为10 int* ptr5 = new int(10); // 动态申请10个int类型的空间 int* ptr6 = new int[10]; delete ptr4; delete ptr5; delete[] ptr6; //格式一一对应 }注意:申请&释放一个空间 -> new & delete;
申请&释放连续的空间 -> new[] & delete[]。
3.2、new和delete操作自定义类型
new/delete 和 malloc/free 的最大区别,就是 new/delete 除了会开空间,还会调用构造函数/析构函数。
cpp
//现有一个 A类
int main()
{
A* p1 = (A*)malloc(sizeof(A));
A* p2 = new A(1);
free(p1);
delete p2;
A* p3 = (A*)malloc(sizeof(A) * 10);
A* p4 = new A[10];
free(p3);
delete[] p4;
return 0;
}
4、operator new 与 operator delete 函数
operator new 其实就是malloc的套个公司换个名的事,不过operator new解决了malloc申请完要手动验证是否申请成功,operator new是不需要管的,他自己会处理,申请失败了会抛异常。
operator delete同理也就是free套个公司换个名的事。
5、new 和 delete 的实现原理
5.1、内置类型
内置类型对于new/delete 与 malloc/free来说,基本是一样的,只不过对于单个空间和连续空间,用的是 new/delete 和 new[]/delete[];对于空间申请失败,new是抛异常,malloc是返回NULL。
5.2、自定义类型
new 的原理:
调用operator new函数申请空间,再调用构造函数对申请的空间进行构造。
底层:malloc + 构造
delete 的原理:
先调用析构函数,对申请的资源进行清理与释放。
底层:析构 + free
new T[N] 的原理:
调用operator new[]函数,实际是调用operator new函数申请N个对象空间;在申请的空间上进行N次构造函数的执行。
delete[] 的原理:
先调用N次析构函数,对N个对象申请的资源进行清理和释放;再调用operator delete[]函数,实际调用operator delete函数释放空间。
6、定位new表达式(placement-new)
定位new表达式的使用场景是配合着内存池进行使用的。内存池:生活费小金库,妈妈每月定期给我、爸爸、姐姐生活费,我们日常开销就在自己的生活费小金库里面取,不需要有一笔消费。就问妈妈要。放在内存池里面的空间只是有一些空间放那,我们可以找他要空间,但是对于自定义类型对象,要来空间的并没有调用构造函数进行初始化,这个工作就交给了 定位new表达式。
定位new表达式的使用方法:new(指针,指向空间)类型 / new(指针,指向空间)类型(实参,初始化值)
cpp
int main()
{
A* p1 = (A*)malloc(sizeof(A));
new(p1)A;
p1->~A(); // 成员函数并不包含在对象里,但是得通过对象去公共存储池里去调用
free(p1);
A* p2 = (A*)malloc(sizeof(A));
new(p2)A(10);
p2->~A();
free(p2);
return 0;
}
7、malloc/free 和 new/delete 的区别
相同点:在堆上申请空间,用户手动释放。
不同点:
1、malloc和free是函数;new和delete是操作符。
2、malloc申请空间不会初始化;new会初始化。
3、malloc申请空间需要计算申请空间大小;new申请多个空间,只要在 [] 里输入你想开的对象个数。
4、malloc返回值是void*,C++中,必须强转;new不需要,他后面跟的就是类型。
5、malloc申请空间失败返回NULL,使用时必须手动判空;new不需要,不过要捕获异常。
6、申请自定义类型时,malloc/free不会调用构造函数和析构函数;new在申请空间后会调用构造函数对实例化出的对象进行初始化,delete会先调用析构函数,将申请的资源进行清理和释放,再释放空间。



