Question

I was practising placement new for my learning. Initially I thought that placement new will manage memory automatically and not make variables overlap but I think this is not the case(Please correct me and highlight upon this). The below code seems to assign new variables at the same address location.

int arr[2] = {};
cout<<arr<<endl;
for(int i = 0; i<2;i++)
{
    int *x = new(arr) int(i);
    cout<<*x<<" "<<x<<endl;
} 

correcting it to the below code seems to solve the problem(any suggestions? and is it correct?)

int arr[2] = {};
cout<<arr<<endl;
for(int i = 0; i<2;i++)
{
    int *x = new(arr+i) int(i);
    cout<<*x<<" "<<x<<endl;
}

Also, there is a doubt which I need to clarify. Is the above practice good(maybe not as it might overflow the container upon changing the loop condition) or placement new containers should only be used to assign variables at one go.

Any better approach to assign variables using placement new if I want to assign variables in a single container NOT at one go and check for boundary leaks as well.

Was it helpful?

Solution 2

Placement new is also very useful for writing exception-safe code and reducing the requirements on a type because you can separate memory allocation from object construction.

For example,

new T[size]

allocates memory and default constructs size objects of type T.

operator new(sizeof(T) * size)

Operator new, however, only allocates memory and does not require default construction of type T. You can then use placement new to construct objects in that allocated memory. This is useful because there are many classes that don't offer default construction, which you could not use in the first example.

Be aware that when using placement new you should explicitly call the destructor for any objects you wish to destroy instead of calling delete. Also, if you used operator new to allocate the memory you should use operator delete to free it. E.G.

auto pBlock = operator new(sizeof(T)); // allocate memory for T   
new (pBlock) T(value); // construct T in place
auto pT = static_cast<T*>(pBlock); // convert the pointer to something useful
pT->~T(); // destruct T
operator delete(pBlock); // free memory

OTHER TIPS

You yourself have answered the question , Basically placement new is to be used when you want to create an object and tell it which memory address it should be using.

A typical use of placement new would be to Create an object on Shared memory

From: http://www.drdobbs.com/creating-stl-containers-in-shared-memory/184401639

C++ STL Containers in Shared Memory Imagine placing STL containers, such as maps, vectors, lists, etc., in shared memory. Placing such powerful generic data structures in shared memory equips processes using shared memory for IPC with a powerful tool. No special data structures need to be designed and developed for communication through shared memory. In addition, the full range of STL's flexibility can be used as an IPC mechanism. STL containers manage their own memory under the covers. When an item is inserted into an STL list, the list container automatically allocates memory for internal data structures to hold the inserted item. Consider placing an STL container in shared memory. The container itself allocates its internal data structure. It is an impossible task to construct an STL container on the heap, copy the container into shared memory, and guarantee that all the container's internal memory is pointing to the shared-memory area.

Process A does the following:

//Attach to shared memory
void* rp = (void*)shmat(shmId,NULL,0);
//Construct the vector in shared
//memory using placement new
vector<int>* vpInA = new(rp) vector<int>*;
//The vector is allocating internal data
//from the heap in process A's address
//space to hold the integer value
(*vpInA)[0] = 22;
Process B does the following:
vector<int>* vpInB =
  (vector<int>*) shmat(shmId,NULL,0);

//problem - the vector contains internal 
//pointers allocated in process A's address 
//space and are invalid here 
int i = *(vpInB)[0];

The whole point of placement new it to completely circumvent C++'s memory management. A "normal" new will allocate the necessary memory, and then initialize it. Placement new initializes the address you specify and assumes its ok to overwrite that memory. You almost never need replacement new!

The typical scenario where you might want to use replacement new is to interact with memory that is not in the control of your application. This sometimes happens with embedded systems, or other low-level programming tasks.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top