————————————每一个不曾起舞的日子都是对生命的辜负。
C++之定位new
- 1. 什么是定位new
- 2. 定位new的语法
- 3. 具体实例
1. 什么是定位new
一般的new运算符负责在heap堆中找到一个足以能够满足要求的内存块。
而定位new(Placement new)是C++中的一个操作符,它允许在已分配的内存区域中构造对象。通常,使用new
关键字来创建对象时,系统会自动分配内存并在其上构造对象。而定位new则提供了一种在指定的内存位置上构造对象的能力。
2. 定位new的语法
定位new的语法形式如下:
new (pointer) Type(arguments);
其中,pointer
是一个指向预分配的内存区域的指针,Type
是要构造的对象的类型,arguments
是传递给对象构造函数的参数。
使用定位new时,内存的分配和释放都需要手动管理,因为定位new不会为对象分配新的内存。它只会在预分配的内存位置上调用对象的构造函数来创建对象。
定位new的主要应用场景包括:
- 在特定的内存区域中构造对象,例如在内存池或自定义的内存管理方案中。
- 在已有的对象内存上重新构造对象,以重用已分配的内存而不是分配新的内存。
- 构造对象时需要传递特定的构造参数。
需要注意的是,对于使用定位new构造的对象,必须显式调用对应的析构函数来销毁对象,并手动释放相关的内存。这是因为定位new并不会自动管理内存释放。例如,可以使用obj->~Type()
来调用对象的析构函数来销毁对象。
定位new是一种高级的C++特性,使用时需要谨慎处理内存管理和对象生命周期的问题,确保正确地构造和销毁对象,避免内存泄漏和悬空指针等问题。
3. 具体实例
#include "iostream";
using namespace std;
int main()
{
char buffer[512]; //chunk of memory内存池
int* p1, * p2, * p3, * p4;
//常规new:
p1 = new int[10];
//定位new:
p2 = new (buffer) int[10];
for (int i = 0; i < 10; ++i)
p1[i] = p2[i] = 20 - i;
cout << "p1 = " << p1 << endl; //常规new指向的地址
cout << "buffer = " << (void*)buffer << endl; //内存池地址
cout << "p2 = " << p2 << endl; //定位new指向的地址
cout << "p2[0] = " << p2[0] << endl;
delete[]p1;
p3 = new (buffer) int;
*p3 = 1;
cout << "p3 = " << p3 << endl;
cout << "p3[0] = " << *p3 << endl;
p4 = new (buffer + 10 * sizeof(int)) int;
cout << "p4 = " << p4 << endl;
return 0;
}
ps:在做高并发内存池项目中遇到此情景。