I would like to recycle memory for an object rather than deallocating and reconstructing it. Is the following usage of "placement new" safe, assuming that Foo
in practice does not contain pointers (but might contain functions)?
Also, is the final delete
call safe, and will it correctly call the destructor on the second "new" object, and correctly free the memory afterwards?
#include <new>
struct Foo {
int hello;
int world;
};
int main() {
Foo* foo = new Foo;
// Do something with foo
// Done with foo, writing a new version of foo on top of the old one.
new(foo) Foo();
delete(foo);
}
The simple example above compiles and runs without errors, but I cannot tell by running it whether it might blow up for some reason in a more complex environment.
An explicit call to destructor is only necessary when an object is placed at a particular location in memory by using placement new. Destructor should not be called explicitly when the object is dynamically allocated because the delete operator automatically calls destructor.
Placement new is used when you do not want operator new to allocate memory (you have pre-allocated it and you want to place the object there), but you do want the object to be constructed.
There are two reasons that your destructors aren't being called, one is as kishor8dm pointed out that you are using the operator "new" and because of that the "delete" command must be called explicitly.
A destructor is a member function that is invoked automatically when the object goes out of scope or is explicitly destroyed by a call to delete .
It's safe because the object you're overwriting has a trivial destructor. From n3337, chapter 3.8 (Object lifetime):
4 A program may end the lifetime of any object by reusing the storage which the object occupies or by explicitly calling the destructor for an object of a class type with a non-trivial destructor. For an object of a class type with a non-trivial destructor, the program is not required to call the destructor explicitly before the storage which the object occupies is reused or released; however, if there is no explicit call to the destructor or if a delete-expression (5.3.5) is not used to release the storage, the destructor shall not be implicitly called and any program that depends on the side effects produced by the destructor has undefined behavior.
The delete
call is safe, too. You're calling it on a pointer that you got from new
and there's a live object at that place.
And as you hinted in the question, it could invoke undefined behaviour if the destructor is non-trivial and has side effects - you need to call it explicitly in that case. Whether or not the class contains pointers is not directly important - reusing the storage is safe even in that case, but of course, you could introduce memory leaks and other bugs that way.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With