@Shadow
国服女程序员在线敲代码 撒谎姓倒过来写 ! 快点关注球球了 🎶Ciallo~😎
目录
一、真实内存、虚拟内存
虚拟内存布局图:
各区域功能介绍:
题目练习
二、C++中的内存管理方式
new/delete操作符的使用
内置类型
自定义类型
new与delete的实现原理
内置类型
自定义类型
(1).new的原理
(2).delete的原理
(3).new T[N]的原理
(4).delete[ ]的原理
new与new[ ]内部函数调用导图(复习重点!)
抛异常
三、定位new表达式(placement-new)
四、malloc/free和new/delete的区别
一、真实内存、虚拟内存
| 物理内存 | 实际的RAM硬件,容量有限(如8GB、16GB) |
| 虚拟内存 | 操作系统为每个进程提供的独立地址空间,通过MMU映射到物理内存 |
虚拟内存布局图:

各区域功能介绍:
栈:也叫堆栈–非静态局部变量/函数参数/返回值等等,栈是向下增长的。 堆:用于程序运行时的动态内存分配,堆是可以向上增长的。 数据段:存储全局数据和静态数据。 代码段:可执行代码/只读常量。
题目练习
int 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);
}
选项
:
A
.
栈
B
.
堆
C
.
数据段
(
静态区
)
D
.
代码段
(
常量区
)
答案: 1.C2.C3.C4.A5.A7.A8.A9.A10.D11.A12.B
二、C++中的内存管理方式
new/delete操作符的使用
当new/delete对单个元素申请时,new的功能类似于malloc,delete的功能类似于free。二者搭配使用。 但在进行连续空间的申请时使用new [ ] 与 delete [ ] 。
注意:例如当使用new int[a]{b};进行初始化时 若b<a那么其余元素自动初始化为0。
具体实现如下:
内置类型
int main()
{
//内置类型
//未初始化
int* p1 = new int; //单个申请空间
int* pp1 = new int[5];//多组申请 使用"[ ]"
//初始化
int* p2 = new int(2); //单组初始化
int* pp2 = new int[5] {1, 2, 3, 4, 5};//多组初始化
//销毁
delete p1;
delete p2;
delete[] pp1; //多组销毁 delete[]
delete[] pp2;
return 0;
}
自定义类型
class A
{
public:
A(int a = 1, int b = 2)
:_a(a)
,_b(b)
{
}
private:
int _a ;
int _b ;
};
int main()
{
//自定义类型 一定初始化->一定具有构造函数
A* p1 = new A; //未初始化
//初始化
A* p2 = new A(1,2);
A* p3 = new A(1);
A* p4 = new A(); //匿名对象
//多组申请并初始化
A aa1;
A aa2;
A* paa = new A[2]{ aa1,aa2 };
return 0;
}
new与delete的实现原理
内置类型
如果申请的是内置类型的空间,new和malloc,delete和free基本类似,不同的地方是: new/delete申请和释放的是单个元素的空间,new[]和delete[]申请的是连续空间,而且new在申请空间失败时会抛异常是(下方解释),malloc会返回NULL。
自定义类型
(1).new的原理
- 调用operator new全局函数申请空间。
- 调用构造函数,完成对对象的构造。
(2).delete的原理
- 调用operator delete全局函数释放对象的空间。
- 调用析构函数,完成对象的清理。
(3).new T[N]的原理
- 调用operator new[ ]全局函数。(1次)
- 执行构造函数N次申请。
(4).delete[ ]的原理
- 调用operator delete[ ]全局函数。(1次)
- 执行析构函数N次释放。
注意!!:(3)(4)杭哥讲得有误 此处博文内容正确。若有不同观点欢迎评论区/私聊指正~
new与new[ ]内部函数调用导图(复习重点!)


抛异常
定义:是C++中的一个错误处理机制,指程序在遇到无法正常处理的情况时,抛出一个“异常”将控制权转移给能够处理这个错误的代码。 例如:程序中常设计代码如下(捕获抛异常)
int main()
{
try
{
int flag = 1;
while (1)
{
int* p1 = new int[1024 * 1024]; //1MB
cout << flag << endl;
++flag;
}
}
catch (const exception& e)
{
cout << e.what() << endl;
}
}
三、定位new表达式(placement-new)
功能:处理极少情景下的初始化问题
定位new表达式是在已分配的空间中调用构造函数来初始化一个对象。 构成:1.new(place_ptr)type或者2.new(place_ptr)type(initializer-list) 指针 类型 初始化列表 其中"1.":new(place_ptr)type仅支持自定义类型的初始化—仅适用于无参/全缺省构造函数的自动调用。
int main()
{
//(1)与(2)几乎相同
//(1)
A* p1 = new A(1);
delete p1;
//(2)
A* p1 = (A*)operator new(sizeof(A)); // 申请空间 //A*强转
new(p1)A(1); // 初始化
//~A();
p1->~A();
//operator delete p1;
operator delete (p1);
}





