The placement new is a variant of regular new operator which takes an additional argument telling the address (or value) where the allocation should happen.
MainFunda* xp = new(a) MainFunda;
//Placement new, where a is pointer
Overloading:
The placement syntax can also be overloaded so that now the overloaded operator new can take more than one argument. The first argument is very special, the new gets the first argument as size of the object. This value is secretly calculated and passed by the compiler. The other arguments can take any number and type of values.
MainFunda* xp = new(a, b, c) MainFunda;
//Overloading Placement new syntax
Example:
#include <iostream> //main header
using namespace std; //for namespace
class MainFunda
{
public:
MainFunda()
{
cout << "MainFunda()" << endl;
}
void* operator new(size_t sz, int x, int y, int z)
{
cout << "Overloaded \
new(" << x << ", " << y << ", " << z \
<< "): size=" << sz << endl;
return ::new char[sz];
}
void operator delete(void* m)
{
cout << "Overloaded delete"<< endl;;
free(m);
}
void* operator new[](size_t sz, int x, int y)
{
cout << "Overloaded new(" << x << ", " << y \
<< ") []: size="<< sz << endl;
return ::new char[sz];
}
void operator delete[](void* m)
{
cout << "Overloaded delete[]"<< endl;;
free(m);
}
~MainFunda()
{
cout << "~MainFunda()" << endl;
}
};
int main()
{
MainFunda * ap = new(4,5,6) MainFunda;
delete ap;
MainFunda * aarray= new (8,9) MainFunda[3];
delete [] aarray;
return 0;
}
The output is :
Overloaded new(4, 5, 6): size=1
MainFunda()
~MainFunda()
Overloaded delete
Overloaded new(8, 9) []: size=11
MainFunda()
MainFunda()
MainFunda()
~MainFunda()
~MainFunda()
~MainFunda()
Overloaded delete[]
The same concept is used in placement new, where memory is allocated in some specific locations rather than from heap.
Use-cases of placement new
Multiple use-cases are possible to implement placement new:
1. We may want to place an object in a specific location in memory. This method is generally useful in firmware and embedded systems. In such systems, an object may be synonymous with a particular piece of hardware.
2. We may want to choose specific memory allocators when calling new.
Working example of placement new
In following C++ code, the placement new takes an address of “int” location “x” from caller. It then uses this “int” location address as if this is an allocated address. This means that “placement new” shall not allocate any new memory from heap. In the end, both class A and variable x will point to same memory address.
#include <iostream> //main header
using namespace std;//for namespace
class MainFunda
{
int *ptrData;
public:
MainFunda()
{
cout << "MainFunda()" << endl;
}
void* operator new(size_t sz, int *ptr)
{
cout << "Placement new :"
<< ptr
<< endl;
return ptr;
}
void setValue(int val)
{
*(int*)this = val; //Note the trick
}
void operator delete(void* ptr)
{
cout << "Overloaded delete :"
<< ptr
<< endl;;
}
~MainFunda()
{
cout << "~MainFunda()"
<< endl;
}
};
int main()
{
int x;
int *ptrX = &x;
cout << "Address of x in main():"
<<ptrX
<< endl;
MainFunda * ap = new(ptrX) MainFunda;
//calling placement new
cout << "Address of MainFunda in main():"
<<"
<< ap
<< endl;
ap->setValue(9);
cout << "Value set in x:"
<< x
<< endl;
delete ap;
return 0;
}
The output is:
Address of x in main():0x7ffe4ca7667c
Placement new :0x7ffe4ca7667c
MainFunda()
Address of MainFunda in main():<<0x7ffe4ca7667c
Value set in x:9
~MainFunda()
Overloaded delete :0x7ffe4ca7667c