[The road to C++ practice] positioning new (project record)

v2-51ee98b05ce2ada206b744b6ff86cbd1_r
———————————— Every day without dancing is a disappointment to life.

1. What is positioning new

The general new operator is responsible for finding a block of memory in the heap that is large enough to satisfy the request.

And positioning new (Placement new) is an operator in C++ that allows objects to be constructed in an allocated memory area. Normally, newwhen a keyword is used to create an object, the system automatically allocates memory and constructs the object on it. Positioning new provides the ability to construct an object at a specified memory location.

2. Locating the syntax of new

The syntax for positioning new is as follows:

new (pointer) Type(arguments);

where pointeris a pointer to a pre-allocated memory area, Typeis the type of object to be constructed, and argumentsis a parameter passed to the object constructor.

When using positioned new, the allocation and release of memory need to be managed manually, because positioning new will not allocate new memory for the object. It simply calls the object's constructor on a pre-allocated memory location to create the object.

The main application scenarios for positioning new include:

  1. Construct objects in specific memory regions, such as in memory pools or custom memory management schemes.
  2. Restructures objects on existing object memory to reuse allocated memory instead of allocating new memory.
  3. When constructing an object, specific construction parameters need to be passed.

It should be noted that for objects constructed using positioning new, the corresponding destructor must be called explicitly to destroy the object and the related memory must be released manually. This is because positioning new does not automatically manage memory deallocation. For example, you can obj->~Type()destroy an object by calling its destructor using .

Locating new is an advanced C++ feature. When using it, you need to carefully handle memory management and object life cycle issues, ensure correct construction and destruction of objects, and avoid problems such as memory leaks and dangling pointers.

3. Specific examples

#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: I encountered this situation in the high-concurrency memory pool project.

Guess you like

Origin blog.csdn.net/NEFUT/article/details/130825919