内存管理
c:malloc、calloc、realloc、free
c++:new(不会初始化)、delete
内存管理方式
对于内置类型
//申请和释放单个元素的空间,使用new和delete操作符
int* p1 = new int;//申请1个int类型的空间
delete p1;int* p2 = new int(0);//申请1个int类型的空间并初始化为0
delete p2;//申请和释放连续的空间,使用new[]和delete[]
int* p3 = new int[10];//申请10个int的空间
delete[] p3;int* p4 = new int[10]{0};//申请10个int的空间,全都初始化为0
delete[] p4;
对于内置类型,new/delete相比malloc/free,除了用法不一样,没有其他区别。
对于自定义类型
// new/delete 和 malloc/free最大区别是 new/delete对于【自定义类型】除了开空间还会调用构造函数和析构函数
在申请自定义类型的空间时,new会调用构造函数,delete会调用析构函数,而malloc与free不会。
底层实现(不是重载!)
new和delete是用户进行动态内存申请和释放的操作符,operator new 和operator delete是系统提供的全局函数,new在底层调用operator new全局函数来申请空间,delete在底层通过operator delete全局函数来释放空间。
operator new
operator new:该函数实际通过malloc来申请空间,当malloc申请空间成功时直接返回;申请空间失败,尝试执行空间不足应对措施,如果该应对措施用户设置了,则继续申请,否则抛bad_alloc异常。
char* p1 = new char[1024*1024*10];
等价于
char* p1 = (char*)operator new(1024*1024*10);
但平时直接用new就行,new的底层就是封装了malloc并能抛出异常。
operator delete
operator delete: 该函数最终是通过free来释放空间的。
placement new
定位new表达式是在已分配的原始内存空间中调用构造函数初始化一个对象。
使用格式:
new (place_address) type
或者new (place_address) type(initializer-list)
。其中place_address必须是一个指针,initializer-list是类型的初始化列表。
A* p1 = (A*)malloc(sizeof(A));// p1现在指向的只不过是与A对象相同大小的一段空间,还不能算是一个对象,因为构造函数没有执行
if(p1 == nullptr) {}
new(p1)A;// 注意:如果A类的构造函数有参数时,此处需要传参
----上述代码相当于下面一句----
A a1 = new A;
定位new是在内存池处使用。池化技术,是为了提高效率,如果项目中要频繁向堆申请空间,就可以考虑使用池化技术。