目录
一.C/C++内存分布
二.C语言中动态内存管理方式
三.C++内存管理方式
3.1 new/delete操作内置类型
3.2 new和delete操作自定义类型
四.operator new和operator delete函数
五.new和delete的实现原理
六.malloc/free和new/delete区别
七.内存泄漏
7.1定义和危害
7.2如何避免
补充说明:
参考:C/C++内存分配
可见博客:C语言动态内存管理
这里回顾一下。
C语言用过malloc/calloc/realloc来在堆上动态申请空间,通过free来释放空间。
malloc/calloc/realloc三者区别:
malloc:只是在堆上动态申请多少字节的空间。一般用法:(类型 *)malloc(sizeof(类型)),返回值为void *所以需要强转。
calloc:不仅有malloc的功能,还具有将空间值初始化为0的功能。一般用法:(类型 *)calloc(x,sizeof(类型)),申请x*sizeof(类型)字节的空间。
realloc:是对在堆上申请的空间不够时,进行扩容。返回地址如果原有地址后面扩容空间够,返回原来地址,不够重新在另外一处开辟空间,返回新地址。(void *)realloc(需要扩容空间地址,空间大小)。
由于C++兼容C语言,C语言内存管理方式可以继续在C++中使用。但是有的地方用C语言的方法会比较麻烦,于是C++提出了一种属于自己的内存管理方式:通过new和delete操作符进行动态内存管理。
#include
using namespace std;
int main(){
//在堆上动态申请一个int类型大小空间
int *p1 = new int;
//在堆上动态申请一个int类型大小空间,并初始化为10
int *p2 = new int(10);
//在堆上申请3个int类型大小的空间,相当于一个动态数组
int *p3 = new int[3];
//释放
delete p1;
delete p2;
delete[] p3;
return 0;
}
注意:
用C语言malloc申请自定义类型空间:
通过上面两幅图可以发现,用new和delete操作自定义类型时不仅会开辟空间,而且会自动调用自定义类型的构造函数,delete会自定调用析构函数,而malloc/calloc/realloc和free不会调用。
所以我们就知道,C语言中已经有了malloc/calloc/realloc和free申请和释放空间,C++也可以用,为什么还需要new和delete了。建议在C++中使用new和delete。
new和delete是用户进行动态内存申请和释放的操作符,而operator new和operator delete是系统提供的全局函数,new底层就是通过调用operator new全局函数来申请空间,delete底层通过operator delete全局函数来释放空间。
operator new是通过malloc来申请空间,当malloc申请空间成功直接返回地址,如果申请空间失败返回NULL,但是operator new如果申请空间失败则会抛异常(简单知道,后面学习了解释)。
operator delete是通过free来释放空间的。
operator new/operator delete用法和malloc/free用法一样,并且不会调用构造函数或析构函数,只是operator new申请失败会抛异常。
#include
#include
using namespace std;
class Test{
public:
Test(){
cout << "构造函数" << endl;
}
~Test(){
cout << "析构函数" << endl;
}
};
int main(){
int *p = (int *)operator new(sizeof(int));
operator delete(p);
Test *p1 = (Test *)operator new(sizeof(Test));
operator delete(p1);
return 0;
}
malloc/operator new/new的区别
free/operator delete/delete区别
如果申请的是内置类型的空间,new和malloc,delete和free功能上类似,不同的是用法上new和delete申请和释放的是单个元素的空间,new[]和delete[]释放的是连续空间,并且new空间申请失败会抛异常,malloc是返回空。
new原理是
delete的原理是
new 类型[]原理
delete[]原理
共同点:都是从堆上申请空间并且需要用户手动释放
不同点:
定义:内存泄漏指因为疏忽或者错误导致动态申请的空间不使用后没有释放的情况。内存泄漏并不是内存物理上的消失,而是应用程序动态开辟某段内存后,失去了对该内存的控制。
危害:内存泄漏对短期运行程序并不会产生很大的影响,因为进程结束了,资源就被释放了。对于长期运行的程序出现内存泄漏,影响很大,如操作系统,后台服务等,出现内存泄漏导致响应越来越慢,最终卡死。
1.事先预防。如智能指针。
2.事后差错。利用检测工具。
3.养成良好的编码习惯。