Again with placement new I've found an example on this forum like this:
char *buf = new char[sizeof(string)]; // pre-allocated buffer
string *p = new (buf) string("hi"); // placement new
string *q = new string("hi"); // ordinary heap allocation
But I think here buf is a pointer to an allocated and Constructed dynamic array of default-init characters. So the characters in the array are default initialized and have an indeterminate values.
I guess using the placement new in the second line will constructs objects on the previously constructed array of objects.
Why the user didn't call operator new on the array allocation rather than using new expression?:
char *buf = static_cast<char*>(operator new[](sizeof(string)));
After all I think if buff is a pointer to a dynamic array of non-default-constructible objects then the code will fail to compile using the new expression rather than using the operator new function.
Are my guesses correct?
Here is the link to the original answer:
What uses are there for "placement new"?
Why the user didn't call operator new on the array allocation rather than using new expression?:
We cannot answer that question because we aren't that user. You should ask that from the user - though given that the example was written in 1998 it might not be easy to contact them. My guess: They didn't know that non-placement operator new exists or they didn't know what it is used for. Reusing the memory of an array of char is an intuitive choice in such case.
Note that the example of creating a singular dynamic std::string object makes little sense in the first place (I'm assuming that's what string in the example is).
I have a similar question to you: Why are you using operator new[] in your suggestion and not operator new? Even more importantly, why not use an allocator?
Are my guesses correct?
Correct.
Correct.
This is a question and not a guess. I covered it above.
It would fail. But that's irrelevant since char is default constructible.
char is an object type that is both fundamental and trivial. Creating one doesn't, in practice, touch memory, and making an array of them does not either.
char* foo = new char[10];
and
char *foo = static_cast<char*>(operator new[](10));
end up doing exactly the same thing in machine code, except the second one is a lot more verbose.
There are some subtle differences in the abstract machine; in one a bunch of chars are created, in the other the other they are not on that line. Coming up with a case where that matters is going to require a fair bit of language lawyering effort (I am thinking disposal may be different, and some access might be different, especially in standard versions before c++ fixed the malloc problem).
After all I think if buff is a pointer to a dynamic array of non-default-constructible objects then the code will fail to compile using the new expression rather than using the operator new function.
Sure, but the cast would be code smell, and the point of buf is to be storage for the later placement new. I guess it already is,
void *foo = operator new[](10);
is less bonkers.
Just because you can static cast does not mean you should.
operator new[](sizeof(string)) that's something odd, its incorrect syntax for creating an object. In best case scenario it creates an object in memory implicitly (if operator new implemented as std::malloc call and object is a POD type), without initializing or constructing one. All you can do in that case is to static_cast<char*>(new string); The offered line just would create a string object in dynamic storage and then make it anonymous by replacing type of pointer by char*.
Thing is, for placement new buf is not necessary to point to dynamic memory. It can be a static buffer.It can be a pointer to memory location within a rather large storage used to store multiple objects, a memory pool. New object would constructed at given location.
Note that in case of placement new std::string's data storage is still behaves as it usually does - it allocates character data in dynamic memory. To use some memory pool, programmer should provide appropriate allocator and that's one of purposes for placement new operator.
No, buf isn't an array of objects. It's an array of characters, so basically an array of bytes. And while it was allocated with an array new, its basically being used as a byte pointer.
The use of placement new is if you want to allocate an object at an exact location, but you want to do so following all the rules of C++ object allocation- so constructors called and vtables set up. The usual use case for this is if you're doing your own custom memory allocation and reusing existing memory addresses. Firmware may use this to reuse memory as a pool. Or an RTOS may use it so that it doesn't exceed memory restrictions for a task.
This is actually a poor example of how its used because of that. You'd never new an array then placement new into it. You'd have a pointer to a block of allocated memory lying around, and you'd use placement new into that.
Related
I just learned about the C++ construct called "placement new". It allows you to exactly control where a pointer points to in memory. It looks like this:
#include <new> // Must #include this to use "placement new"
#include "Fred.h" // Declaration of class Fred
void someCode()
{
char memory[sizeof(Fred)];
void* place = memory;
Fred* f = new(place) Fred(); // Create a pointer to a Fred(),
// stored at "place"
// The pointers f and place will be equal
...
}
(example from C++ FAQ Lite)
In this example, the this pointer of Fred will be equal to place.
I've seen it used in our team's code once or twice. In your experience, what does this construct enable? Do other pointer languages have similar constructs? To me, it seems reminiscent of equivalence in FORTRAN, which allows disparate variables to occupy the same location in memory.
It allows you to do your own memory management. Usually this will get you at best marginally improved performance, but sometimes it's a big win. For example, if your program is using a large number of standard-sized objects, you might well want to make a pool with one large memory allocation.
This sort of thing was also done in C, but since there are no constructors in C it didn't require any language support.
It is also used for embedded programming, where IO devices are often mapped to specific memory addresses
Its usefull when building your own container like objects.
For example if you were to create a vector. If you reserve space for a large number of objects you want to allocate the memory with some method that does not invoke the constructor of the object (like new char[sizeof(object) * reserveSize]). Then when people start adding objects into the vector you use placement new to copy them into allocated memory.
template<typename T>
class SillyVectorExample
{
public:
SillyVectorExample()
:reserved(10)
,size(0)
,data(new char[sizeof(T) * reserved])
{}
void push_back(T const& object)
{
if (size >= reserved)
{
// Do Somthing.
}
// Place a copy of the object into the data store.
new (data+(sizeof(T)*size)) T(object);
++size;
}
// Add other methods to make sure data is copied and dealllocated correctly.
private:
size_t reserved;
size_t size;
char* data;
};
PS. I am not advocating doing this. This is just a simplified example of how containers can work.
I've used it when constructing objects in a shared memory segment.
Placement new can be used to create type-safe unions, such as Boost's variant.
The union class contains a buffer as big as the biggest type it's specified to contain (and with sufficient alignment). It placement news objects into the buffer as required.
I use this construct when doing C++ in kernel mode.
I use the kernel mode memory allocator and construct the object on the allocated chunk.
All of this is wrapped in classes and functions, but in the end I do a placement new.
Placement new is NOT about making pointers equal (you can just use assignment for that!).
Placement new is for constructing an object at a particular location. There are three ways of constructing an object in C++, and placement new is the only one that gives you explicit control over where that object "lives". This is useful for several things, including shared memory, low-level device I/O, and memory pool/allocator implementation.
With stack allocation, the object is constructed at the top of the stack, wherever that happens to be currently.
With "regular" new, the object is constructed at an effectively arbitrary address on the heap, as managed by the standard library (unless you've overridden operator new).
Placement new says "build me an object at this address specifically", and its implementation is simply an overload of operator new that returns the pointer passed to it, as a means of getting to the remainder of the machinery of the new operator, which constructs an object in the memory returned by the operator new function.
It's also worth noting that the operator new function can be overloaded with arbitrary arguments (just as any other function). These other arguments are passed via the "new(arg 2, arg3, ..., argN)" syntax. Arg1 is always implicitly passed as "sizeof(whatever you're constructing)".
By controlling the exact placement, you can align things in memory and this can sometimes be used to improve CPU fetch/cache performance.
Never actually saw it in use, though
It can be useful when paging out memory to a file on the hard drive, which one might do when manipulating large objects.
Placement new allows the developer to allocate the memory from preallocated memory chunk. If the system is larger, then developers go for using placement new. Now I am working on a larger avionics software there we allocate the large memory that is required for the execution of application at the start. And we use the placement new to allocate the memory wherever required. It increases the performance to some amount.
seems to me like a way of allocating an object on the stack ..
I've used it to create objects based on memory containing messages received from the network.
I was reading an excellent answer to another question which gave these specific examples:
char[] array = {'a', 'b', 'c', '\0'};
Thing* t = new Thing[size];
t[someindex].dosomething();
I commented that, as good practice, you should add delete[] to the second example, as this is the bit people forget leading to memory leaks.
But I can't remember if you need to delete[] in the first instance. I don't think you do, because there's no new so it's on the stack, but I'm not 100% sure that's right.
I don't think you do, because there's no new so it's on the stack, but I'm not 100% sure that's right.
This reasoning is correct when the array is defined inside a function, and is therefore on the stack. You must never use delete on any objects that have been created on the stack without the use of new. Using delete on stack allocated objects will lead to undefined behavior.
If the definition char[] array = {'a', 'b', 'c', '\0'}; appeared at file scope, however, it will have static storage duration and will not be on the stack, but it still won't have been dynamically allocated and still must not be delete[]d.
So, either way, don't delete[] the array....
You always and only use delete when you have used new and delete[] when you have used new[]. Never mix them. And never mix with (2).
You always and only use free when you have made a classic C allocation like malloc or calloc. Never mix with (1). But don't free memory allocated with alloca ;)
Note that in some cases, the allocation or deallocation can be hidden inside a function or something. For instance, there is a non standard C-function that copies a string like this: char *str = strdup("Hello");. In this case, you should use free(str) even though you did not manually invoke malloc.
So if you do a declaration on the form T t[10] or T[] t={a,b,c} you do NOT deallocate this.
int main()
{
int x;
std::cin << x;
T *a = new T;
delete a;
T *b = new T[x];
delete[] b;
T *c = (T*)malloc(x*sizeof(*c)); // Casting is needed in C++ but not in C
free(c);
// No free or delete for these
T d;
T e[10];
// Assuming a, b and c are instances of T or that you have overloaded the
// operator so that you can write T t=a;
// In either case, you should not free nor delete this
T f[] = {a, b, c};
}
In C, you can use VLA:s like int arr[x] where x is not known at compile time. That's not possible in C++. You don't use free on these arrays either.
I don't think you do, because there's no new so it's on the stack, but I'm not 100% sure that's right.
This is not correct. The standard does not dictate if the objects should be on the stack or the heap. It's up to the compiler, so what happens in reality is a question of how compilers usually solves the task.
Furthermore, the "fact" that statically allocated memory ends up on the stack and dynamically allocated memory ends up on the heap is only true most of the time. Granted, this is usually what happens, but there are some rare cases when it's not. And these occurrences are not so rare or obscure that they can be ignored. Global variables typically does not end up on the stack.
So if memory should be freed/deleted is not a question of if it lives in the stack or the heap. It's about how it has been allocated.
And in modern C++ you very rarely use new, new[], delete or delete[] at all. Instead, you use smart pointers and containers. Look at this link:
What is a smart pointer and when should I use one? and also https://en.cppreference.com/w/cpp/container/vector If you are dealing with old legacy C++, it might be a good idea to refactor it to modern memory management. If you change a new-delete pair to a smart pointer, then you have saved a line. If you change a new without a corresponding delete, then you have solved a bug.
TL;DR
When do you need to delete C-style arrays?
For the case T a[n] (with or without initialization) you should never do it. For the case T *a = new T[n] you should always do it. Whenever you have used new you should delete it afterwards, and never otherwise. (There may be some rare exceptions to this. See the rest of the post.)
Also, AFIK, there is no established definition of "C-style arrays". Personally, I would not consider T *a = new T[n] an array at all. I would not consider T *a = malloc(n*sizeof(*a)) an array either. The reason is simple. Pointers and arrays are NOT the same thing, and this goes for both C and C++. This question is about C, but is applicable for C++ too: Is an array name a pointer?
I commented that, as good practice, you should add delete[] to the
second example, as this is the bit people forget leading to memory
leaks.
You also should add delete[] in order to get destructors called. In addition to releasing some internally allocated memory, destructors may have other side effects.
Semantically, new and delete (and new[] and delete[]) come in pairs. new starts the object lifetime, and delete ends the object lifetime started by new. However, usually it is advisable to make deletion hidden inside a smart pointer.
The idea is to bind object lifetimes to the notion of "object ownership". Static objects are owned by the whole program. Automatic objects are owned by the code block they are defined in. Dynamic objects have no clearly defined ownership in C++ language itself, although the language gives the tools to implement the notion of object ownership by the writers of the code.
Smart pointers are one of these tools. std::unique_ptr is used when at every moment of time the object has only one owner, but you may want to pass ownership between blocks of code. std::shared_ptr is used when there can be multiple owners, and the object lifetime should end when the last owner stops to be interested in the object.
If I do this:
// (1.)
int* p = new int;
//...do something
delete p;
// (2.)
class sample
{
public:
sample(){}
~sample(){}
};
sample* pObj = new sample;
//...do something
delete pObj;
Then how does C++ compiler know that object following delete is built-in data type or a class object?
My other question is that if I new a pointer to an array of int's and then I delete [] then how does compiler know the size of memory block to de-allocate?
The compiler knows the type of the pointed-to object because it knows the type of the pointer:
p is an int*, therefore the pointed-to object will be an int.
pObj is a sample*, therefore the pointed-to object will be a sample.
The compiler does not know if your int* p points to a single int object or to an array (int[N]). That's why you must remember to use delete[] instead of delete for arrays.
The size of the memory block to de-allocate and, most importantly, the number of objects to destroy, are known because new[] stores them somewhere, and delete[] knows where to retrieve these values. This question from C++ FAQ Lite shows two common techniques to implement new[] and delete[].
It knows the difference between them because of the type of the pointer you pass to it: It is undefined behavior to pass a different pointer type than you allocated with (except you may pass a pointer to a base class, if the destructor is virtual, of course).
The size of an array will be stored somewhere. It's like in C where you can malloc a certain amount of memory, and free afterwards - the runtime will have to manage to know the size allocated previously.
For example it can store the count of elements prior to the buffer allocated. The Standard explicitly allows the compiler to pass a different request size to the allocation function (operator new[]) in case of array allocations - this can be used by the compiler to stick the count into, and offset the address returned by the new expression by the size of that counter.
It doesn't!
All what delete does is that it invokes the destructor of the type, which is "no action" in the case of primitive types. Then, it passes the pointer to ::operator delete (or an overloaded version if you like), and thats operator returns back the memory(a memory manager issue). i.e. You can write your own memory manager easily in C++ if you like, the language provides one by default!
The compiler knows the type of the object being deleted and writes different code for you to achieve the right results:
delete p can call the run time delete with the size of an int.
delete pObj can call pObj->~sample() first, then delete with the size of sample
I think with arrays, there is a hidden value for the size of the array, so it could be that the whole array is deleted in one go.
Then how does C++ compiler know that object following delete is built-in data type or a class object?
Because at compile time the compiler tracks the types of each object and plants the appropraite code.
My other question is that if I new a pointer to an array of int's and then I delete [] then how does compiler know the size of memory block to de-allocate?
It does not. This is kept track of by the runtime system.
When you dynamically allocate an array the runtime library associates the size of the object with the object thus when it deletes it it knows (by looking up the associated value) the size.
But I guess you want to know how it does the association?
This depends on the system and is an implementation detail. But a simple stratergy is to allocate an extra 4 bytes store the size in the first four bytes then return a pointer to the 4th byte allocated. When you delete a pointer you know that the size is the 4 bytes before the pointer. Note: I am not saying your system is using this technique but it is one stratergy.
For the first (non-array) part of the question, the answers above indicating that the compiler inserts code to de-allocate the appropriate number of bytes based on the pointer type, don't quite provide a clear answer for me... the delete operator 1) calls a destructor if applicable and then 2) calls the "operator delete()" function... it is operator delete which actually de-allocates. I can see compiler-generated code playing a role in part (1), ie. the destination address of the destructor must be inserted. But in part (2), it is a pre-existing library function handling the de-allocation, so how will it know the size of the data? The global operator delete--which, I believe is used in all cases unless a class-member/overloaded-global version is defined by the programmer--accepts only a void* argument spec'ing the start of the data, so it can't even be passed the data size.
I've read things indicating the compiler-generated code idea, as well as things suggesting that the global operator delete for non-arrays simply uses free(), ie. it knows the data size not by the pointer type, but by looking a few bytes before the data itself, where the size will have been stashed by new/malloc. The latter is the only solution that makes sense to me, but maybe someone can enlighten me differently...
What is wrong with using delete instead of delete[]?
Is there something special happening under the covers for allocating and freeing arrays?
Why would it be different from malloc and free?
Objects created with new[] must use delete[]. Using delete is undefined on arrays.
With malloc and free you have a more simple situation. There is only 1 function that frees the data you allocate, there is no concept of a destructor being called either. The confusion just comes in because delete[] and delete look similar. Actually they are 2 completely different functions.
Using delete won't call the correct function to delete the memory. It should call delete[](void*) but instead it calls delete(void*). For this reason you can't rely on using delete for memory allocated with new[]
See this C++ FAQ
[16.13] Can I drop the [] when
deleteing array of some built-in type
(char, int, etc)?
No!
Sometimes programmers think that the
[] in the delete[] p only exists so
the compiler will call the appropriate
destructors for all elements in the
array. Because of this reasoning, they
assume that an array of some built-in
type such as char or int can be
deleted without the []. E.g., they
assume the following is valid code:
void userCode(int n) {
char* p = new char[n];
...
delete p; // ← ERROR! Should be delete[] p !
}
But the above code is wrong, and it
can cause a disaster at runtime. In
particular, the code that's called for
delete p is operator delete(void*),
but the code that's called for
delete[] p is operator
delete[](void*). The default behavior
for the latter is to call the former,
but users are allowed to replace the
latter with a different behavior (in
which case they would normally also
replace the corresponding new code in
operator new[](size_t)). If they
replaced the delete[] code so it
wasn't compatible with the delete
code, and you called the wrong one
(i.e., if you said delete p rather
than delete[] p), you could end up
with a disaster at runtime.
Why does delete[] exist in the first place?
Whether you do x or y:
char * x = new char[100];
char * y = new char;
Both are stored in char * typed variables.
I think the reason for the decision of delete, and delete[] goes along with a long list of decisions that are in favor of efficiency in C++. It is so that there is no enforced price to do a lookup of how much needs to be deleted for a normal delete operation.
Having 2 new and new[] seems only logical to have delete and delete[] anyway for symmetry.
The difference is that delete will only delete the entire memory range, but will only call the destructor for 1 object. delete[] will both delete the memory and call the destructor for every single object. If you do not use delete[] for arrays, it's only a matter of time before you introduce a resource leak into your application.
EDIT Update
According to the standard, passing an object allocated with new[] to delete is undefined. The likely behavior is that it will act as I described.
Stroustrup talks about the reasons for separate new/new[] and delete/delete[]` operators in "The Design and Evolution of C++" in sections 10.3 through 10.5.1:
10.3 Array Allocation - discusses that they wanted a way to allow arrays of objects to be allocated using a separate scheme from allocation single objects (ie., allocating arrays from a separate store). Adding the array versions of new and delete was a solution for this;
10.5.1 Deallocating Arrays - discusses how a problem with deallocating arrays using just a single delete operator is that there needs to be more information than just the pointer in order to determine if the pointer points to the first element of an array or if it just points to a single object. Instead of "complicating the common case of allocating and deallocating individual objects", the delete[] operator is used to handle arrays. This fits in with the general C++ design philiosophy of "don't pay for what you don't use".
Whether this decision was a mistake or not is debatable - either way has good arguments, but we have what we have.
The reason for this requirement is historical and because new type and new type [size] return different things that need to be cleaned up differently.
Consider this code
Foo* oneEntry = new Foo;
Foo* tenEntries = new Foo[10];
These both return a Foo* pointer, the difference is the second call will result in the Foo constructor being called 10x, and there being roughly 10x as much memory.
So now you want to free your objects.
For a single object you would call delete - e.g. delete oneEntry. This calls the objects destructor and and deallocates the memory.
But here's the problem - oneEntry and tenEntries are both just Foo pointers. The compiler has no idea whether they point to one, ten, or a thousand elements.
When you use the special syntax of delete []. This tells the compiler "this is an array of objects, figure out the count and then destruct them all".
What really happens is that for new type [size] the compiler secretly stores 'size' somewhere else. When you call delete[] it knows that this secret value exists so it can find out how many objects are in that block of memory and destruct them.
The question you could then ask is "why doesn't the compiler always store the size?"
That's a great question and it dates back to the early days of C++. There was a desire that for built-in types (char, int, float, etc) the following would be valid for C++;
int* ptr = new int;
free(ptr);
int* ptr = (int*)malloc(sizeof(int) * someSize);
delete ptr;
The reasoning behind this was an expectation that people would provide libraries that returned dynamically allocated memory, and users of these libraries would have no way of knowing whether to use free/delete.
This desire for compatibility meant that the size of an array could not be stored as part of the array itself and had to be kept elsewhere. Because of this overhead (and remember, this was back in the early 80's) it was decided to do this book keeping only for arrays and not single-elements. Thus arrays need a special delete syntax that looks up this value.
The reason malloc/free do not have this problem is that they simply deal with blocks of memory and do not have to worry about calling constructors/destructors.
As to the "why" in the title: one of the design goals of C++ was that there wouldn't be any hidden costs. C++ was also developed at a time when every byte of memory still mattered a whole lot more than it does today. Language designers also like orthogonality: if you allocate the memory with new[] (instead of new), you should free it with delete[].
I don't think there's any technical reason that new[] couldn't stick an "I'm an array" flag in the header of the memory block for delete (no more delete[]) to look at later.
new and delete are different from malloc and free in that malloc and free only allocate and free memory; they don't call ctors or dtors.
When you use new[] to allocate an array, you are actually telling C++ the size of the array. When you use malloc, you are instead telling it how much memory is allocated. In the former case, freeing based on the size of the array would not make sense. In this case, it does. But since there is no difference between a pointer for an array vs. for a single object, a separate function is needed.
I just learned about the C++ construct called "placement new". It allows you to exactly control where a pointer points to in memory. It looks like this:
#include <new> // Must #include this to use "placement new"
#include "Fred.h" // Declaration of class Fred
void someCode()
{
char memory[sizeof(Fred)];
void* place = memory;
Fred* f = new(place) Fred(); // Create a pointer to a Fred(),
// stored at "place"
// The pointers f and place will be equal
...
}
(example from C++ FAQ Lite)
In this example, the this pointer of Fred will be equal to place.
I've seen it used in our team's code once or twice. In your experience, what does this construct enable? Do other pointer languages have similar constructs? To me, it seems reminiscent of equivalence in FORTRAN, which allows disparate variables to occupy the same location in memory.
It allows you to do your own memory management. Usually this will get you at best marginally improved performance, but sometimes it's a big win. For example, if your program is using a large number of standard-sized objects, you might well want to make a pool with one large memory allocation.
This sort of thing was also done in C, but since there are no constructors in C it didn't require any language support.
It is also used for embedded programming, where IO devices are often mapped to specific memory addresses
Its usefull when building your own container like objects.
For example if you were to create a vector. If you reserve space for a large number of objects you want to allocate the memory with some method that does not invoke the constructor of the object (like new char[sizeof(object) * reserveSize]). Then when people start adding objects into the vector you use placement new to copy them into allocated memory.
template<typename T>
class SillyVectorExample
{
public:
SillyVectorExample()
:reserved(10)
,size(0)
,data(new char[sizeof(T) * reserved])
{}
void push_back(T const& object)
{
if (size >= reserved)
{
// Do Somthing.
}
// Place a copy of the object into the data store.
new (data+(sizeof(T)*size)) T(object);
++size;
}
// Add other methods to make sure data is copied and dealllocated correctly.
private:
size_t reserved;
size_t size;
char* data;
};
PS. I am not advocating doing this. This is just a simplified example of how containers can work.
I've used it when constructing objects in a shared memory segment.
Placement new can be used to create type-safe unions, such as Boost's variant.
The union class contains a buffer as big as the biggest type it's specified to contain (and with sufficient alignment). It placement news objects into the buffer as required.
I use this construct when doing C++ in kernel mode.
I use the kernel mode memory allocator and construct the object on the allocated chunk.
All of this is wrapped in classes and functions, but in the end I do a placement new.
Placement new is NOT about making pointers equal (you can just use assignment for that!).
Placement new is for constructing an object at a particular location. There are three ways of constructing an object in C++, and placement new is the only one that gives you explicit control over where that object "lives". This is useful for several things, including shared memory, low-level device I/O, and memory pool/allocator implementation.
With stack allocation, the object is constructed at the top of the stack, wherever that happens to be currently.
With "regular" new, the object is constructed at an effectively arbitrary address on the heap, as managed by the standard library (unless you've overridden operator new).
Placement new says "build me an object at this address specifically", and its implementation is simply an overload of operator new that returns the pointer passed to it, as a means of getting to the remainder of the machinery of the new operator, which constructs an object in the memory returned by the operator new function.
It's also worth noting that the operator new function can be overloaded with arbitrary arguments (just as any other function). These other arguments are passed via the "new(arg 2, arg3, ..., argN)" syntax. Arg1 is always implicitly passed as "sizeof(whatever you're constructing)".
By controlling the exact placement, you can align things in memory and this can sometimes be used to improve CPU fetch/cache performance.
Never actually saw it in use, though
It can be useful when paging out memory to a file on the hard drive, which one might do when manipulating large objects.
Placement new allows the developer to allocate the memory from preallocated memory chunk. If the system is larger, then developers go for using placement new. Now I am working on a larger avionics software there we allocate the large memory that is required for the execution of application at the start. And we use the placement new to allocate the memory wherever required. It increases the performance to some amount.
seems to me like a way of allocating an object on the stack ..
I've used it to create objects based on memory containing messages received from the network.