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

定位new是C++的一个高级特性,允许在已分配的内存上构造对象,常用于内存池或自定义内存管理。它不负责内存分配,需要手动管理。文章通过实例展示了如何使用定位new,并强调了正确管理对象生命周期以避免内存问题的重要性。
摘要由CSDN通过智能技术生成

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:在做高并发内存池项目中遇到此情景。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

每天都要进步呀~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值