Strange C++ new operator usage [duplicate] - c++

This question already has answers here:
What uses are there for "placement new"?
(25 answers)
Closed 9 years ago.
While digging in a C++ project, I encountered a strange usage of C++'s new operator:
int arr[5];
ClassA* a = new(arr) ClassA();
Would you please help me understand this syntax?

It's the placement new syntax - it allows you to construct an object at the pointed-to location in memory. Consider a "normal" use of new:
X *p = new X;
...
delete p;
You can achieve the same effect by doing:
#include <new>
...
void *buffer = ::operator new(sizeof(X));
X *p = new (buffer) X;
...
p->~X();
::operator delete(buffer);
The latter allocates enough memory to hold an X (without constructing an X in it), then explicitly constructs an X in the allocated memory. Later, it explicitly destructs the X it created and then deallocates the memory that contained it.
See also the C++ FAQ: http://www.parashift.com/c++-faq/placement-new.html

This syntax is called the placement new syntax. It is typically used to construct an object on a pre-allocated buffer. This is useful when building a memory pool, a garbage collector or simply when performance and exception safety are paramount (there's no danger of allocation failure since the memory has already been allocated, and constructing an object on a pre-allocated buffer takes less time).
char *buf = new char[sizeof(string)]; // pre-allocated buffer
string *s1 = new (buf) string("test1"); // placement new
string *s2 = new string("test2"); //ordinary new
When it comes to deallocation, there is no placement delete that automatically does the magic. You should not deallocate every object that is using the memory buffer. Instead you should destruct each object manually, then delete[] only the original buffer

The new() operator can take a size (size in bytes) nothrow_value (returns a null pointer instead of an bad_alloc exception) or pointer(construct the object in the already allocated memory pointed at by this pointer) argument, and in the usage you describe it is creating a new object at the memory location pointed to by arr. For a decent guide on it I would look at this link.
In the case you cited it is using the pointer for arr to create its new instance of ClassA in.

Related

Which is more optimal: `new` or `calloc`? [duplicate]

This question already has answers here:
In what cases do I use malloc and/or new?
(20 answers)
Closed 8 years ago.
I use calloc, I've read that, calloc internally calls new handler, so what should I go for?
Should I use new operator(which allocate fast) or calloc(which can allocate and initialize memory as well)?
The question cannot really be answered, because it's based on the incorrect assumption that new merely allocates memory but doesn't initialize it. The contrary is the fact:
new not only allocates memory (unless you use "placement new"), it also calls some objects constructor. I.e. new does much more than calloc.
In C++, if you feel that you need to allocate some memory for e.g. some variable-sized array, consider using the standard containers first, e.g. prefer
std::vector<char> buf( 1024 );
over
char *buf = new char[1024];
Well, everyone's told you about new not initialising memory etc, but they forgot about value-initialization syntax:
char *buffer = new char[size]();
So I would argue that you always use new. If you want to initialise the memory, use the above syntax. Otherwise, drop the parentheses.
calloc isn't really comparable to new; it's closer to operator new (they are not the same). calloc will zero out the memory allocated whereas operator new and malloc won't. new constructs an object in the storage location but calloc doesn't.
// Using calloc:
my_object* p = static_cast<my_object*>(std::calloc(1, sizeof(my_object)));
::new(static_cast<void*>(p)) my_object(10);
// Using operator new:
my_object* p = static_cast<my_object*>(::operator new(sizeof(my_object)));
::new(static_cast<void*>(p)) my_object(10);
// using new:
my_object* p = new my_object(10);
Should I use new operator(which allocate fast) or calloc(which can allocate and initialize memory as well)?
In C++ you should never use *alloc memory function (malloc, calloc, free, etc). They lead you to create code that is unsafe for C++ (for C it is fine).
You should also use most specialized (higher level) code constructs whenever available.
That means:
prefer new/new[]/delete/delete[] over malloc/calloc/free
prefer smart pointers over raw pointers
prefer abstractions over raw pointer data (i.e. use std::vector/std::array/etc instead of new[] and delete[], use std::unique_ptr<T>/std::shared_ptr<T> instead of T*, etc.

how do you delete an object allocated with placement new

there are quite a few faces for the new operator in c++, but I'm interested in placement new.
Suppose you allocate memory at a specific memory location
int memoryPool[poolSize*sizeof(int)];
int* p = new (mem) int; //allocates memory inside the memoryPool buffer
delete p; //segmentation fault
How can I correctly deallocate memory in this case?
What if instead of built-in type int I would use some class called myClass?
myClass memoryPool[poolSize*sizeof(myClass )];
myClass * p = new (mem) myClass ; //allocates memory inside the memoryPool buffer
delete p; //segmentation fault
Thanks for your help.
In the first case, there's no point in using placement new, since int doesn't have a constructor.
In the second case, it's either pointless (if myClass is trivial) or wrong, since there are already objects in the array.
You use placement new to initialise an object in a block of memory, which must be suitably aligned, and mustn't already contain a (non-trivial) object.
char memory[enough_bytes]; // WARNING: may not be properly aligned.
myClass * c = new (memory) myClass;
Once you've finished with it, you need to destroy the object by calling its destructor:
c->~myClass();
This separates the object's lifetime from that of its memory. You might also have to release the memory at some point, depending on how you allocated it; in this case, it's an automatic array, so it's automatically released when it goes out of scope.
In your case there is no need to deallocate it, your int array will be deallocated once you return from your function. You should only call explicitly your destructor:
p->~myclass();
to keep you buffer correctly aligned use std::aligned_storage, look in here for example:
http://www.cplusplus.com/reference/type_traits/aligned_storage/

Dynamically allocating memory on stack

There is such code:
#include <iostream>
int main()
{
int a;
int* p = new (&a) int(2);
std::cout << a << std::endl;
// delete p; error BLOCK TYPE IS INVALID
std::cin.get();
return 0;
}
The output is:
2
Why is it possible to dynamically allocate memory on stack? (I thought that heap is the right place to do this). And, why does delete operator return error in this case, but new operator work?
This is using the placement new syntax. Placement new does not allocate memory at all, rather, it is a way to construct an object at a particular location. In this example, the memory comes from the stack. It doesn't have to. delete has issues because you didn't new the memory.
There are ways to dynamically allocate memory from the stack (alloca) but that's not what is happening here.
int* p = new (&a) int(2);
This is called placement-new. It doesn't allocate memory. It constructs the object in the same memory of a. In placement new, it's the user who specifies the memory region where new operator constructs the object. In your code above, you specify the memory region by writing (&a) expression just after the new keyword. Since &a is not a dynamically allocated memory, you cannot delete it:
delete p; //runtime-error
It would give runtime error, it attempts to delete the memory where the variable a resides.
However, if you dynamically allocate the memory, then you can do delete it. Lets suppose, A is some class, then you should be doing this:
char *buffer = new char[sizeof(A)]; //allocate memory of sizeof(A);
///ASSUMPTION: the buffer is properly align as required by the type A
//use placement-new to construct an object at the specified memory region
A *pA = new (buffer) A(/*..parameters..*/);
//...
//incorrect way to delete the memory!
//delete pA; //incorrect
//before deleting the memory you should be calling the destructor explicitly as
pA->~A(); //call the destructor explicitly - must do it
//now deallocate the memory as
delete []buffer;
This is simplest example of placement-new which explains the syntax only. But the story doesn't end here; it is the beginning and to make it work properly, the memory pointed to by buffer has to be aligned properly for the object type, and in the above example, I simply assumed so. In the real code, you cannot make such dangerous assumption. Now read this FAQ:
What is "placement new" and why would I use it?
This is called placement new: http://www.parashift.com/c++-faq-lite/dtors.html#faq-11.10
You can optionally pass an address to new, and it will only call the object's constructor (if it has one). Because no memory was allocated, it would be an error to deallocate it with delete. Simply call the object's destructor (if it has one) and you're done.
C++ separates the notions of memory allocation and object lifetime. This is perhaps one of the most important "new" aspects of the language compared to C. In C there is no such distinction because variables are entirely determined by their memory, while in C++ objects have a more abstract notion of a "state" which is distinct from the underlying memory.
Let's look at memory first:
{
char buf[100]; // automatic allocation, scoped lifetime
}
{
void * p = std::malloc(100); // dynamic allocation, manually managed
void * q = ::operator new(100); // essentially identical
// ...
::operator delete(q); // manual deallocation
std::free(p); // ditto
}
On the other hand, an object's lifetime is a separate topic:
{
Foo x; // automatic storage, scoped lifetime.
// Implies automatic memory allocation for sizeof(Foo) bytes.
}
{
Foo * px = ::new Foo; // dynamic storage, manual lifetime,
// implies dynamic allocation via ::operator new()
Foo * py = ::new (q) Foo; // dynamic storage and manual lifetime, uses memory at q
// ...
delete px; // destroy object _and_ deallocate memory
py->~Foo(); // destroy object. Memory was never our business to start with.
}
As you can see, the separation of memory and object lifetime adds a lot of flexibility: We can have dynamic objects living in automatic memory, or take care of allocation ourselves and reuse memory for repeated object constructions. The standard new and delete expressions combine allocation and construction, but this is only a shortcut for the most frequently used operations. In principle, you're entirely free to handle memory and object lifetime separately.
This idea underpins the notion of allocators, which are a core concept in the C++ standard library.

Can a call delete on the pointer which is allocated with the placement new?

Can we call delete on the pointer which is allocated with the placement new? If no then why? Please explain in details.
I know that there is no placement delete. But I wonder why just delete opetator can not delete the memory without caring how that memory on which the pointer points is allocated?
delete is doing two things:
Calls destrucor
Frees memory
And I see no reaason for delete not to be able to call either of these two operations on the object which was created by placement new. Any idea about reasons?
You must only call delete on pointers that were created with operator new. If you use placement new with a memory location that was allocated by the normal operator new then you may safely use delete on it (provided you get the types and pointers right). However, you can use placement new on any memory, so you usually will manage that memory some other way and call the object's destructor manually.
For instance, in this convoluted and usually unnecessary scenario, it is safe to delete the memory you used placement new on, but only because you allocated it with new before:
char* mem = new char[sizeof(MyObject)];
MyObject* o = new (mem) MyObject;
// use o
o->~MyObject(); // with placement new you have to call the destructor by yourself
delete[] mem;
However, this is illegal:
char mem[16]; // create a buffer on the stack, assume sizeof(MyObject) == 16
MyObject* o = new (mem) MyObject; // use stack memory to hold a MyObject
// note that after placement new is done, o == mem
// pretend for this example that the point brought up by Martin in the comments didn't matter
delete o; // you just deleted memory in the stack! This is very bad
Another way to think of it is that delete only deallocates memory allocated previously by the normal new. With placement new, you do not have to use memory that was allocated by the normal new, so with the possibility of not having been allocated by normal new, delete cannot deal with it.
EDIT1: I know that there is no placement delete. But I wonder why just
delete opetator can not delete the memory without caring how that
memory on which the pointer points is allocated?
Because each flavour of memory allocation uses some implementation specific tracking of the memory (usually a header block that precedes the user address) and this make the allocation/deallocation to work only when paired up correctly:
new must pair with delete
new[] must pair with delete[] (most implementations though forgive mixing the newand new[])
malloc and frieds must pair with free
CoTaskMemAlloc pairs with CoTaskMemFree
alloca pairs with nothing (stack unwinding takes care of it)
MyCustomAllocator pairs with MyCustomFree
Attempting to call the wrong deallocator will result in unpredictable behavior( most likely seg fault now or later). Therefore calling delete on memory allocated by anything else other than new will result in bad things.
Furthermore the placement new may be called on any address, may not even be an allocated address. It can be called on an address located in the middle of some larger object, it may be called on a memory mapped region, it may be called on a raw virtual committed region, anything goes. delete woul attempt, in all these cases, to do what its implementation tell him to do: subtract the header size, interpret it as a new header, link it back into the heap. Kaboom.
The one that know how to release the memory of a placement new address is you, since you know exactly how was that memory allocated. delete will only do what it knows, and it may not be the right thing.
No, since delete not only calls the destructor but also frees the memory, but if you used placement new you must have allocated the memory yourself using malloc() or stack. You do, however, have to call the destructor yourself. Also see the C++ FAQ.
No. There is no placement-delete expression.
Typical scenario:
void * const addr = ::operator new(sizeof(T)); // get some memory
try {
T * const pT = new (addr) T(args...); // construct
/* ... */
p->~T(); // nap time
}
catch (...) {
}
::operator delete(addr); // deallocate
// this is _operator_-delete, not a delete _expression_
Note that the placement-new operator does have a corresponding delete operator which is mandated to be precisely void ::operator delete(void* [, size_t]) { }, a no-op; this is what gets called if the constructor of T throws an exception.
No, because a placement new doesn't allocate any memory. You use placement new on previously allocated raw memory. The only thing it does is call the constructor of the object.

Which to use - "operator new" or "operator new[]" - to allocate a block of raw memory in C++?

My C++ program needs a block of uninitialized memory and a void* pointer to that block so that I can give it to a third party library. I want to pass control of the block lifetime to the library, so I don't want to use std::vector. When the library is done with the block it will call a callback that I have to supply and that will deallocate the block. In C I would use malloc() and later free().
In C++ I can either call ::operator new or ::operator new[] and ::operator delete or operator delete[] respectively later:
void* newBlock = ::operator new( sizeOfBlock );
// then, later
::operator delete( newBlock );
Looks like both ::operator new and ::operator new[] have exactly the same signature and exactly the same behavior. The same for ::operator delete and ::operator delete[]. The only thing I shouldn't do is pairing operator new with operator delete[] and vice versa - undefined behavior. Other than that which pair do I choose and why?
Use new with a single object and new[] with an array of objects. So, for example:
int* x = new int; // Allocates single int
int* y = new int[5]; // Allocates an array of integers
*x = 10; // Assignment to single value
y[0] = 8; // Assignment to element of the array
If all you are doing is allocating a memory buffer, then allocate an array of char as in:
int bufferlen = /* choose a buffer size somehow */
char* buffer = new char[bufferlen];
// now can refer to buffer[0] ... buffer[bufferlen-1]
However, in C++, you should really use std::vector for arbitrary arrays, and you should use std::string for character arrays that are to be interpreted or used as strings.
There is no reason to invoke ::operator new or ::operator new[] explicitly rather than using the ordinary syntax for these calls. For POD and primitive types (e.g. char) no initialization will take place. If you need to get a void* buffer, then simply use static_cast to convert char* to void*.
The advantage of the C++ new operators over C's malloc() and free() is that the former throws an exception if there is not enough memory, rather than returning NULL.
Regarding choosing new(size) and new[] for character buffers, I'd advocate the latter since it is less likely to surprise people maintaining the code later i.e. char* buf = new char[size] and delete[] buf.
The values in the buffer will not be initialised, and there is no range-checking - you have to build a nice C++ object to do that for you, or use an existing object such as std::vector or std::string.
The question cannot be answered sensibly.
Firstly, it is said that the program 'needs' a block of uninitialized memory but, from the code sample given, it seems that the program 'needs' a block of uninitialized and UNTYPED memory which seems not very C++ or OO.
Secondly, a std::vector gives sole and automatic control over a block of typed memory that may or may not change in size according to its use. You can lose this control if an instance of std::vector is created on the heap and tracked with raw pointers just as for any other C or C++ object such as a void* memory block.
Thirdly, what is the intended use of this memory block? The answer to this may or may not dictate the use of operator new or operator new[]. In the design of this program, is there a single interpretation of this memory block? What ownership semantics do you require, if any? Etc, etc.
for allocating memory to array/list use new[] other than that use new...