您现在的位置是:首页 >其他 >【C++修炼之路】定位new(项目记录)网站首页其他

【C++修炼之路】定位new(项目记录)

每天都要进步呀~ 2024-06-19 00:01:01
简介【C++修炼之路】定位new(项目记录)

v2-51ee98b05ce2ada206b744b6ff86cbd1_r
————————————每一个不曾起舞的日子都是对生命的辜负。

1. 什么是定位new

一般的new运算符负责在heap堆中找到一个足以能够满足要求的内存块。

而定位new(Placement new)是C++中的一个操作符,它允许在已分配的内存区域中构造对象。通常,使用new关键字来创建对象时,系统会自动分配内存并在其上构造对象。而定位new则提供了一种在指定的内存位置上构造对象的能力。

2. 定位new的语法

定位new的语法形式如下:

new (pointer) Type(arguments);

其中,pointer 是一个指向预分配的内存区域的指针,Type 是要构造的对象的类型,arguments 是传递给对象构造函数的参数。

使用定位new时,内存的分配和释放都需要手动管理,因为定位new不会为对象分配新的内存。它只会在预分配的内存位置上调用对象的构造函数来创建对象。

定位new的主要应用场景包括:

  1. 在特定的内存区域中构造对象,例如在内存池或自定义的内存管理方案中。
  2. 在已有的对象内存上重新构造对象,以重用已分配的内存而不是分配新的内存。
  3. 构造对象时需要传递特定的构造参数。

需要注意的是,对于使用定位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;
}

image-20230523140454224

ps:在做高并发内存池项目中遇到此情景。

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。