文章目录
-
- 一、内存管理
- 二、C++内存管理
-
- [(1) new 和delete 关键字](#(1) new 和delete 关键字)
- [(2) 类成员的new 和 delete](#(2) 类成员的new 和 delete)
- [(3) 底层原理(operator new 和 operator delete)](#(3) 底层原理(operator new 和 operator delete))
- 三、自定义类型多开4字节空间存储对象个数
- 四、内存池
一、内存管理
-
内存分布:
栈 -> 局部变量,形参,常变量;
堆 -> 动态申请的空间;
数据段(静态区)-> static静态变量, 全局变量;
代码段(常量区)-> 字面量,字符串。
-
解释变量存在哪里?
cint 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"; // 局部变量,栈区。-> "abcd" 存在常量区,char2 拷贝字符串数据到栈区。 // *char2 是字符'a',也存在栈区。 const char* pChar3 = "abcd"; // const 修饰的常变量,pChar3存在栈区,指向常量区的字符串。 // *pChar3 是字符串"abcd", 在常量区。 int* ptr1 = (int*)malloc(sizeof(int) * 4); // ptr1 是存储在栈上的局部变量,存储堆区的地址。 // *ptr1 动态开辟的地址,在堆区。 int* ptr2 = (int*)calloc(4, sizeof(int)); // 开辟4个int类型的空间,并初始化为0。 int* ptr3 = (int*)realloc(ptr2, sizeof(int) * 4); // 动态扩容,调整空间大小(后面内存足够->原地扩,不够->异地扩) free(ptr1); free(ptr3); // 一旦使用realloc, 原来地址ptr2 已经被free()了,不能在使用,也不能在free()。 }
二、C++内存管理
(1) new 和delete 关键字
关键字要匹配
- new int -> delete
- new int[10] -> delete[]
c
int main()
{
// 动态申请一个int类型的空间,默认随机值,不会初始化。
int* p1 = new int;
// 动态申请一个int类型的空间,并初始化
int* p2 = new int(10);
// 动态申请10个int类型的空间
int* p3 = new int[10];
// 动态申请10个int类型的空间
int* p4 = new int[10] {10, 9, 8, 7};
// 释放空间
delete p1;
delete p2;
// 释放连续的空间
delete[] p3;
delete[] p4;
return 0;
}
(2) 类成员的new 和 delete
c
class A
{
public:
A(int a=0)
:_a(a)
{
cout << "A():" << this << endl;
}
~A()
{
cout << "~A()" << endl;
}
private:
int _a;
};
int main()
{
// 动态开辟一个自定义类型 A 空间。-> 调用构造函数
A* p1 = new A(10);
delete p1; // 释放空间 -> 调用析构函数
A* p2 = new A[10]{ 1,2,3,4,5,6,7,8 };
delete[] p2;
return 0;
}
- new/delete 和 malloc/free 最大的区别是:new/delete 对于【自定义类型】除了开空间外,还会调用构造函数和析构函数
- 在动态申请空间时,new 调用构造,delete 调用析构。malloc和free不会。
(3) 底层原理(operator new 和 operator delete)
- new 调用 operator new + 构造
- operator new 调用 malloc()
- 相当于new封装operator new, operator new 封装 malloc()
- new 的底层仍然是 malloc()函数
- new Type[N] 调用 operator new Type[N]
- operator new Type[N] 调用 operator new + N次构造
- operator new 调用 malloc()
- delete 调用 operator delete + 析构
- operator delete 调用 free()
- C++中 new 动态开辟失败, 使用try{}catch(exception& e){} 捕获异常
c
try
{
function();
}
catch (const exception& e)
{
cout << "e.what()" << endl;
}
**总结:**new 最终还是调用malloc()实现; delete 最终调用free() 实现。
new -> operator new -> malloc()
delete -> operator delete -> free()
三、自定义类型多开4字节空间存储对象个数
c
A* p1 = new A[10];
-
在显示写了析构函数的情况下:
-
new 开辟了44字节空间,多的4字节空间存储对象的个数,用来对p1 释放空间时 使用。
/* ______________________________ |__4Byte__|_____40Byte_______| /|\ /|\ | | | p1指向位置 | 实际开空间位置 */
-
-
不显示写析构函数,不会多开辟4字节空间。
-
对于内置类型,也不多开辟空间。
四、内存池
池转换技术, 线程池, 连接池...