目录
C/C++内存分布
在C/C++中,都有一块虚拟地址,内部井然有序的将代码分成了几部分,如下表:
栈:又叫堆栈,存放着非静态局部变量、函数参数、返回值等,栈是向下生长的
内存映射段:是高效的I/O映射方式,用于装载一个共享的动态内存库。用户可使用系统接口创建共享内存,做进程间通信
堆:用于程序运行时动态内存分配,栈是向上生长的
数据段:存储全局数据和静态数据
代码段:存储可执行代码、只读常量
C语言内存管理
C语言中内存管理的方式有四种:malloc、calloc、realloc、free
具体讲解如下:
C语言:动态内存管理(malloc,calloc,realloc,free)_malloc失败会返回null吗-CSDN博客
C++内存管理:
C语言中的内存管理方式C++中是可以使用的,但已经不适合C++使用了
C++中是通过new和delete操作符进行动态内存管理
int main()
{
int* ptr = new int;
return 0;
}
使用new关键字来开辟内存空间,new的后面需要跟一个类型,这就是一个int类型的空间
int main()
{
int* ptr = new int(5);
return 0;
}
在类型的后面加个(),就是初始化,里面的值就是要初始化的值
int main()
{
int* ptr = new int[3];
return 0;
}
在类型的后面加个[]和一个数字n,这个看起来像数组一样的东西就是开辟出来了n块类型的空间
所以这里是开辟了3块int类型的空间
这几块相应的delete应该这样使用
int main()
{
int* ptr1 = new int;
int* ptr2 = new int(5);
int* ptr3 = new int[3];
delete ptr1;
delete ptr2;
delete[] ptr3;
return 0;
}
用了[]开辟的空间我们就使用delete[]来释放空间,否则就不需要
这里一定要匹配使用
在new int[n]开空间的时候,编译器会多开一点空间记录下这个数字n
在调用delete[]就会找到前面的这个n从而释放空间
如果不匹配使用也能调用正确可能是因为编译器优化了,导致恰好正确
new和delete的原理
new
在我们调用new时其实是调用了operator new函数申请空间
而operator new函数内部又调用了malloc来开辟空间
delete
调用delete是调用了operator delete函数释放对象的空间
而operator delete函数内部又调用了free来释放空间
malloc/free和new/delete的区别
1. malloc和free是函数,new和delete是操作符
2. malloc不会初始化,new会初始化
3. malloc申请空间失败会返回NULL,而new是抛异常
4. 申请自定义类型对象时malloc/free只会单纯的开辟空间和释放空间,而new申请空间后会调用对象的构造函数完成对象的初始化,delete也会调用相应的析构函数来释放空间,这也是为什么C++要有一套自己的内存管理方式
5. malloc要开多少空间需要手动计算,new只需要知道空间个数即可
6. malloc返回值时void*,需要强转,而new不需要
完