1.C/C++内存分布
C/C++中内存主要分为:栈、堆、数据段、代码段、内存映射段。
-
栈:又叫堆栈,存放非静态局部变量,函数的参数,返回值、栈是向下增长的。
-
堆:用于程序运行时动态分配。
-
数据段:存放全局变量,静态变量。
-
代码段:存放可执行的代码和常量。
-
**内存映射段:**是高效的I/O映射方式,用于装载一个共享的动态内存库。用户可使用系统接口
创建共享共享内存,做进程间通信。
2.C语言中动态内存管理方式
C语言中主要使用malloc,calloc,realloc和free来进行动态内存管理,那么malloc,calloc,realloc有什么区别呢?
1.函数原型与参数不同
-
malloc :
void* malloc(size_t size);- 只接收1个 参数:要分配的总字节数。
-
calloc :
void* calloc(size_t nmemb, size_t size);- 接收2个 参数:元素个数 和 单个元素大小 。实际分配的总字节数为
nmemb * size。
- 接收2个 参数:元素个数 和 单个元素大小 。实际分配的总字节数为
-
realloc :
void* realloc(void *ptr, size_t new_size);- 接收2个 参数:原先的内存指针 和 新的总字节数。它用于调整已存在内存块的大小。
2.初始化行为不同
-
malloc :不会初始化 内存。分配的内存中存储的是残留的"脏数据"(随机值)。如果你需要清零,必须手动调用
memset。 -
calloc :会初始化为 0 。分配完成后,它会将内存块中的所有字节全部置为
0(保证数据安全)。 -
realloc :不会初始化新增的部分 。它只负责调整大小,原有的数据内容会被保留 (如果缩小,缩掉的部分丢失;如果扩大,新增加的空间不会清零,同样是脏数据)。
3.C++内存管理
C++使用new和delete来进行动态内存管理
1.new和delete用于内置类型
cpp
//动态申请一个int 类型的空间
int* p1 = new int;
//动态申请一个int 类型的空间并初始化为10
int* p2 = new int(10);
//动态申请是个int 类型的空间
int* p3 = new int[10];
delete p1;
delete p2;
delete[] p3;
注意,申请单个空间用new和delete,申请连续空间用new\[\]和delete\[\],要搭配使用。
2.new和delete用于自定义类型
cpp
class A
{
public:
A(int a = 0)
: _a(a)
{
cout << "A():" << this << endl;
}
~A()
{
cout << "~A():" << this << endl;
}
private:
int _a;
};
int main() {
//new和delete与malloc和free对内置类型的处理几乎没有区别,但对自定义类型,new和delete会调用构造函数和析构函数,malloc和free不调用
A* p1 = (A*)malloc(sizeof(A));
A* p2 = new A(10);
free(p1);
delete p2;
int* p3 = (int*)malloc(sizeof(int)); // C
int* p4 = new int;
free(p3);
delete p4;
A* p5 = (A*)malloc(sizeof(A) * 10);
A* p6 = new A[10];
free(p5);
delete[] p6;
return 0;
}
4.operator new与operator delete****函数
new和delete操作符在底层实际上是调用operator new与operator delete两个全局函数,operator new也是通过malloc来申请空间,申请成功就直接返回,否则就执行用户提供的空间不足应对措施,如果用户提供就继续申请,否则就抛异常,operator delete通过free来释放空间。

5.new和delete的实现原理
1.内置类型
对于内置类型,new和delete与malloc和free基本类似,不同在于new和delete申请和释放的是单个空间,new\[\]和delete\[\]申请和释放的是连续空间,new申请失败会抛异常,malloc申请失败会返回NULL。
2.自定义类型
new和delete
new:
- 调用operator new完成空间的申请
- 调用构造函数,完成对对象的初始化构造
delete:
- 调用析构函数,完成对对象资源空间的清理
- 调用operator delete完成空间的释放
new\[\]和delete\[\]
new\[\]:
- 调用operator new\[\],实际上operator new\[\]调用operator new完成N次空间的申请
- 调用N次构造函数,完成对对象的初始化构造
delete\[\]:
- 调用N次析构函数,完成对对象资源空间的清理
- 调用operator delete\[\],operator delete\[\]调用operator delete完成N次空间的释放