placement delete inside or outside destructor - c++

I found the following code while reading placement new operator.
#include <iostream>
using namespace std;
class MyClass {
public:
// Placement new operator
void* operator new (size_t sz, void* v) {
cout << "Placement new invoked" << endl;
return v;
}
~MyClass() {
// Cleanup
}
};
int main()
{
// Create a buffer to store the object
int buffer[16];
cout << "Starting address of my buffer = " << &buffer << endl;
// Create the object. Use placement new
MyClass* obj = new (buffer) MyClass();
cout << "Location of my object = " << obj << endl;
// Don't delete object created with placement delete
// Call the destructor explicitly
obj->~MyClass();
}
I have few questions related to delete object which was created using placement new:
what is the clean up code needs to write in destructor in order to
free memory which was occupied obj in buffer memory.
is it not needed to define placement delete, if yes whether it needs to be inside destructor or outside destructor. If it is outside destructor how it will be called ?

Regular new does two things:
allocate memory for your object
construct your object in that memory space.
Placement new means you manage one of those and the other is managed as before.
You allocate / provide the memory for your object
Constructor is called in that memory space.
The reverse is delete of which the regular delete does the following:
Invoke the destructor of the object to clean-up
Free the memory that was allocated for it.
Note that they are done in reverse order for obvious reasons. You cannot free the memory that contains information about what needs to be cleaned up, unti you have finished using that memory. Whereas in construction you need to get hold of the memory first.
In what you call placement delete but is really the reverse of placement new, you need to perform the first step of destruction but not the second. Thus you call the object's destructor, and then you can free up the memory it uses / use it for something else.
The most common example of usage of placement new is in the implementation of std::vector which requires a contiguous buffer for its data, and which lets you reserve ahead (and if you don't it will probably do it for you). That part allocates the memory but does not construct the objects in it. Thus when they are constructed later, placement new is used.

what is the clean up code needs to write in destructor in order to free memory which was occupied obj in buffer memory
The destructor should just do what any destructor does: clean up any resources managed by the object. In this case, it doesn't manage any resources, so there's no need to do anything.
It shouldn't do anything special according to how the storage for the object itself was allocated. Managing that storage is the job for custom new and delete operators, when required.
is it not needed to define placement delete
No. Placement-new is used to construct an object in storage that you're managing yourself, and it's your responsibility to free that storage yourself. In this case, the storage is automatic, so it's automatically freed when the function exits.
Just as the allocator for placement-new does nothing (just returning the provided pointer to pre-allocated storage), so the corresponding deallocator would do nothing; and so it doesn't exist. You just need to destroy the object by calling its destructor directly, before disposing of the storage yourself.

The first thing to ask is: what are you trying to do? If you
define a placement operator new in a class, then that is the
only operator new which will be found when you write new
MyClass; you must always specify the extra arguments. And in
almost every case where you define a class specific operator
new, you should also define a class specific operator delete;
otherwise the global operator delete function will be called
when you write delete p, and that generally won't work.
If your goal is to systematically require separation of
allocation and initialization, and that is why you are defining
a member operator new, then you can provide a no-op operator
delete; if the constructor of the class can throw, then you'll
also want to provide a placement operator delete, since this is
what will be called if the constructor of a newed object exits
via an exception. There is no other way to call it, however.
When providing placement operator new, you must provide
a default operator delete which does the right thing; and when
providing several operator new for the same type, you need to
memorize somehow in each allocation which one was called, in
order to dispatch in the non-placement operator delete.
And by the way, just allocating a buffer as a local variable
does not guarantee sufficient alignment for anything but the
declared buffer type.
EDIT:
Just an example of what would be needed for the operator
delete functions (which must be members):
void operator delete( void* p ) {}
void operator delete( void* p, void* ) {}

Related

How to choose the adequate, delete or delete[]? [duplicate]

What is the difference between delete and delete[] operators in C++?
The delete operator deallocates memory and calls the destructor for a single object created with new.
The delete [] operator deallocates memory and calls destructors for an array of objects created with new [].
Using delete on a pointer returned by new [] or delete [] on a pointer returned by new results in undefined behavior.
The delete[] operator is used to delete arrays. The delete operator is used to delete non-array objects. It calls operator delete[] and operator delete function respectively to delete the memory that the array or non-array object occupied after (eventually) calling the destructors for the array's elements or the non-array object.
The following shows the relations:
typedef int array_type[1];
// create and destroy a int[1]
array_type *a = new array_type;
delete [] a;
// create and destroy an int
int *b = new int;
delete b;
// create and destroy an int[1]
int *c = new int[1];
delete[] c;
// create and destroy an int[1][2]
int (*d)[2] = new int[1][2];
delete [] d;
For the new that creates an array (so, either the new type[] or new applied to an array type construct), the Standard looks for an operator new[] in the array's element type class or in the global scope, and passes the amount of memory requested. It may request more than N * sizeof(ElementType) if it wants (for instance to store the number of elements, so it later when deleting knows how many destructor calls to done). If the class declares an operator new[] that additional to the amount of memory accepts another size_t, that second parameter will receive the number of elements allocated - it may use this for any purpose it wants (debugging, etc...).
For the new that creates a non-array object, it will look for an operator new in the element's class or in the global scope. It passes the amount of memory requested (exactly sizeof(T) always).
For the delete[], it looks into the arrays' element class type and calls their destructors. The operator delete[] function used is the one in the element type's class, or if there is none then in the global scope.
For the delete, if the pointer passed is a base class of the actual object's type, the base class must have a virtual destructor (otherwise, behavior is undefined). If it is not a base class, then the destructor of that class is called, and an operator delete in that class or the global operator delete is used. If a base class was passed, then the actual object type's destructor is called, and the operator delete found in that class is used, or if there is none, a global operator delete is called. If the operator delete in the class has a second parameter of type size_t, it will receive the number of elements to deallocate.
This the basic usage of allocate/DE-allocate pattern in c++
malloc/free, new/delete, new[]/delete[]
We need to use them correspondingly. But I would like to add this particular understanding for the difference between delete and delete[]
1) delete is used to de-allocate memory allocated for single object
2) delete[] is used to de-allocate memory allocated for array of objects
class ABC{}
ABC *ptr = new ABC[100]
when we say new ABC[100], compiler can get the information about how many objects that needs to be allocated(here it is 100) and will call the constructor for each of the objects created
but correspondingly if we simply use delete ptr for this case, compiler will not know how many objects that ptr is pointing to and will end up calling of destructor and deleting memory for only 1 object(leaving the invocation of destructors and deallocation of remaining 99 objects). Hence there will be a memory leak.
so we need to use delete [] ptr in this case.
The operators delete and delete [] are used respectively to destroy the objects created with new and new[], returning to the allocated memory left available to the compiler's memory manager.
Objects created with new must necessarily be destroyed with delete, and that the arrays created with new[] should be deleted with delete[].
When I asked this question, my real question was, "is there a difference between the two? Doesn't the runtime have to keep information about the array size, and so will it not be able to tell which one we mean?" This question does not appear in "related questions", so just to help out those like me, here is the answer to that: "why do we even need the delete[] operator?"
C++ delete[] operator ensures that Destructor for all object allocated with new[] is called. The following example demonstrates the same. Also, delete[] must be preferred (if new[] used previously) when the class has a non-default destructor to release the acquired resources. Otherwise, it might result in memory leaks.
Common Code:-
#include <iostream>
using namespace std;
class memTest{
public:
static int num;
memTest(){
cout<<"Constructor from object " << num++ << endl;
}
~memTest(){
cout<<"Destructor from object " << --num << endl;
}
};
int memTest::num=0;
Example 1:- use of new[] and delete may result in undefined behavior.
int main() {
memTest* Test1=new memTest[3];
delete Test1; //<-----
return 0;
}
Output 1:-
Constructor from object 0
Constructor from object 1
Constructor from object 2
Destructor from object 2 //<-----
Example 2: The correct behavior is using new[] and delete[].
int main() {
memTest* Test1=new memTest[3];
delete[] Test1; //<-----
return 0;
}
Output 2:-
Constructor from object 0
Constructor from object 1
Constructor from object 2
Destructor from object 2
Destructor from object 1 //<-----
Destructor from object 0 //<-----
delete is used for one single pointer and delete[] is used for deleting an array through a pointer.
This might help you to understand better.

C++ What is the difference between delete and delete [ ]? [duplicate]

What is the difference between delete and delete[] operators in C++?
The delete operator deallocates memory and calls the destructor for a single object created with new.
The delete [] operator deallocates memory and calls destructors for an array of objects created with new [].
Using delete on a pointer returned by new [] or delete [] on a pointer returned by new results in undefined behavior.
The delete[] operator is used to delete arrays. The delete operator is used to delete non-array objects. It calls operator delete[] and operator delete function respectively to delete the memory that the array or non-array object occupied after (eventually) calling the destructors for the array's elements or the non-array object.
The following shows the relations:
typedef int array_type[1];
// create and destroy a int[1]
array_type *a = new array_type;
delete [] a;
// create and destroy an int
int *b = new int;
delete b;
// create and destroy an int[1]
int *c = new int[1];
delete[] c;
// create and destroy an int[1][2]
int (*d)[2] = new int[1][2];
delete [] d;
For the new that creates an array (so, either the new type[] or new applied to an array type construct), the Standard looks for an operator new[] in the array's element type class or in the global scope, and passes the amount of memory requested. It may request more than N * sizeof(ElementType) if it wants (for instance to store the number of elements, so it later when deleting knows how many destructor calls to done). If the class declares an operator new[] that additional to the amount of memory accepts another size_t, that second parameter will receive the number of elements allocated - it may use this for any purpose it wants (debugging, etc...).
For the new that creates a non-array object, it will look for an operator new in the element's class or in the global scope. It passes the amount of memory requested (exactly sizeof(T) always).
For the delete[], it looks into the arrays' element class type and calls their destructors. The operator delete[] function used is the one in the element type's class, or if there is none then in the global scope.
For the delete, if the pointer passed is a base class of the actual object's type, the base class must have a virtual destructor (otherwise, behavior is undefined). If it is not a base class, then the destructor of that class is called, and an operator delete in that class or the global operator delete is used. If a base class was passed, then the actual object type's destructor is called, and the operator delete found in that class is used, or if there is none, a global operator delete is called. If the operator delete in the class has a second parameter of type size_t, it will receive the number of elements to deallocate.
This the basic usage of allocate/DE-allocate pattern in c++
malloc/free, new/delete, new[]/delete[]
We need to use them correspondingly. But I would like to add this particular understanding for the difference between delete and delete[]
1) delete is used to de-allocate memory allocated for single object
2) delete[] is used to de-allocate memory allocated for array of objects
class ABC{}
ABC *ptr = new ABC[100]
when we say new ABC[100], compiler can get the information about how many objects that needs to be allocated(here it is 100) and will call the constructor for each of the objects created
but correspondingly if we simply use delete ptr for this case, compiler will not know how many objects that ptr is pointing to and will end up calling of destructor and deleting memory for only 1 object(leaving the invocation of destructors and deallocation of remaining 99 objects). Hence there will be a memory leak.
so we need to use delete [] ptr in this case.
The operators delete and delete [] are used respectively to destroy the objects created with new and new[], returning to the allocated memory left available to the compiler's memory manager.
Objects created with new must necessarily be destroyed with delete, and that the arrays created with new[] should be deleted with delete[].
When I asked this question, my real question was, "is there a difference between the two? Doesn't the runtime have to keep information about the array size, and so will it not be able to tell which one we mean?" This question does not appear in "related questions", so just to help out those like me, here is the answer to that: "why do we even need the delete[] operator?"
C++ delete[] operator ensures that Destructor for all object allocated with new[] is called. The following example demonstrates the same. Also, delete[] must be preferred (if new[] used previously) when the class has a non-default destructor to release the acquired resources. Otherwise, it might result in memory leaks.
Common Code:-
#include <iostream>
using namespace std;
class memTest{
public:
static int num;
memTest(){
cout<<"Constructor from object " << num++ << endl;
}
~memTest(){
cout<<"Destructor from object " << --num << endl;
}
};
int memTest::num=0;
Example 1:- use of new[] and delete may result in undefined behavior.
int main() {
memTest* Test1=new memTest[3];
delete Test1; //<-----
return 0;
}
Output 1:-
Constructor from object 0
Constructor from object 1
Constructor from object 2
Destructor from object 2 //<-----
Example 2: The correct behavior is using new[] and delete[].
int main() {
memTest* Test1=new memTest[3];
delete[] Test1; //<-----
return 0;
}
Output 2:-
Constructor from object 0
Constructor from object 1
Constructor from object 2
Destructor from object 2
Destructor from object 1 //<-----
Destructor from object 0 //<-----
delete is used for one single pointer and delete[] is used for deleting an array through a pointer.
This might help you to understand better.

C++: delete with placement parameter [duplicate]

Why C++ hasn't placement delete that directly corresponds to the placement new, i.e. calls the destructor and calls appropriate placement delete operator?
For example:
MyType *p = new(arena) MyType;
...
//current technique
p->~MyType();
operator delete(p, arena);
//proposed technique
delete(arena) p;
operator delete is unique in being a non-member or static member function that is dynamically dispatched. A type with a virtual destructor performs the call to its own delete from the most derived destructor.
struct abc {
virtual ~abc() = 0;
};
struct d : abc {
operator delete() { std::cout << "goodbye\n"; }
};
int main() {
abc *p = new d;
delete p;
}
(Run this example.)
For this to work with placement delete, the destructor would have to somehow pass the additional arguments to operator delete.
Solution 1: Pass the arguments through the virtual function. This requires a separate virtual destructor for every static member and global operator delete overload with different arguments.
Solution 2: Let the virtual destructor return a function pointer to the caller specifying what operator delete should be called. But if the destructor does lookup, this hits the same problem of requiring multiple virtual function definitions as #1. Some kind of abstract overload set would have to be created, which the caller would resolve.
You have a perfectly good point, and it would be a nice addition to the language. Retrofitting it into the existing semantics of delete is probably even possible, in theory. But most of the time we don't use the full functionality of delete and it suffices to use a pseudo-destructor call followed by something like arena.release(p).
Probably because there was syntax for explicitly calling a destructor without deallocation (exactly as in your question), but no syntax for explicit construction in raw memory?
Actually there is a placement delete which is called by the implementation for an object that was "allocated" using placement new if the constructor threw an exception.
From Wikipedia.
The placement delete functions are called from placement new expressions. In particular, they are called if the constructor of the object throws an exception. In such a circumstance, in order to ensure that the program does not incur a memory leak, the placement delete functions are called.
The whole point of placement new is to separate object creation from its memory management. So it makes no sense to tie it back during object destruction.
If memory for your objects is from heap and you want same lifetime for objects and their memory just use operator new and operator delete, maybe overriding them if you want any special behavior.
Placement new is good for example in vector, which keeps a large chunk of raw memory and creates and destroys object inside of it, but without releasing memory.

When a constructor is called explicitly is the initializer and member variables constructed?

In the use of "placement new" it is suggested to call the constructor and destructor explicitly.
In this case will the objects initialized in the initializer section of a class also get properly constructed?
Same too with explicitly calling the destructor? Do the member objects get destroyed properly?
In the use of "placement new" it is
suggested to call the constructor and
destructor explicitly.
It's not correct to say that "you call constructor explicitly", as constructors don't have names ($12.1/1).
In this case will the objects
initialized in the initializer section
of a class also get properly
constructed?
Yes. Why do you doubt it? Placment new only means that the new operator will not allocate any memory, rather will use the memory which you pass in placement new, to construct the object. The object gets constructed in the memory which you pass.
Same too with explicitly calling the
destructor? Do the member objects get
destroyed properly?
Yes.
In the use of "placement new" it is suggested to call the constructor and destructor explicitly.
I don't think so. It will say that you need to call the destructor explicitly.
In this case will the objects initialized in the initializer section of a class also get properly constructed?
Apart from the supplying of the memory all other aspects of placement new are the same as normal new. So rather than dynamically allocating memory it just uses the supplied pointer.
Same too with explicitly calling the destructor?
You can (if you feel naught) call the destructor explicitly on any object. It will call the user defined (or compiler generated) class destructor as normal. The reason you need to explicitly do it for objects created via placement new is that you can call delete on these objects. This is because delete assumes the object was created in dynamically allocated memory and tries to re-cycle that memory after the destructor has been called.
Do the member objects get destroyed properly?
Yes.
If we think of new like this:
// not real code
template<class T> T* new(void* location = NULL) (ArgumentsForT)
{
// If you do not provide location (normal usage)
// then we allocate some memory for you.
if (location == NULL)
{ location = malloc(sizeof(T)); // Use of malloc() is just an example
}
((T*)location)->Constructor(ArgumentsForT);
return (T*)location;
}
So placement new will work just like normal new.
Looking at the call to delete
template<typename T> void delete(T* obj)
{
if (obj != NULL)
{
obj->~T();
free(obj);
}
}
The trouble here is that delete can not tell if the memory was allocated by new or if the memory was allocated by the user and passed into new (placement new). So it always calls free on the memory. If you used placement new then you may not have dynamically allocated the memory (or the memory is still being used for something else).
char x[sizeof(T)]; // don't do this (memory may not be aligned correctly).
T* obj = new (x) T();
delete obj; // FAIL. The memory was not dynamically allocated.
// Delete will try and re-claim this memory for re-yse
// Even if the memory is local.
// This is why on placement new you need to call the destructor
obj->~T();

why destructor is not called implicitly in placement new"?

As referenced in this site...
http://www.parashift.com/c++-faq-lite/dtors.html#faq-11.10
But i did not find the reason, why we should explicitly call the desturctor?
You can think of it as a call to delete, but since you used placement new, you don't want to use delete, as that would attempt to free the memory. If you wanted it to be called automatically, you could use RAII:
// Could use a templated version, or find an existing impl somewhere:
void destroy_fred(Fred* f) {
f->~Fred();
}
void someCode()
{
char memory[sizeof(Fred)];
void* p = memory;
boost::shared_ptr<Fred> f(new(p) Fred(), destroy_fred);
// ...
// No need for an explicit destructor, cleaned up even during an exception
}
Normally, newed objects are destructed when delete is called. delete is never called for placement new, so you have to figure out when to destruct the object yourself, and do so explicitly.
You can't call ordinary delete because that would attempt free the memory, which was not allocated with ordinary new, so you call the destructor directly and then handle the underlying memory allocation depending on the architecture you are using.
Normally, an object is created using new, and destroyed when you call delete on the object. However, because 'delete' will also try to free the underlying memory back to the heap, you should never call delete on an object which which was instantiated using placement new.
Nevertheless, (no matter how it was allocated) every object ought to be destroyed (because its destructor might do something important).
Therefore instead of the object's being destroyed using delete, you have to destroy the object yourself, and do so explicitly, by invoking its destructor as shown in the FAQ you cited.
The example from your link:
void someCode()
{
char memory[sizeof(Fred)];
void* p = memory;
Fred* f = new(p) Fred();
...
f->~Fred(); // Explicitly call the destructor for the placed object
}
"placement new" return the memory offset that we provide. Right after new the compiler adds a call to the ctor ("placement new" is a also a trick to explicity call a ctor).
"memory" is allocated in the stack so we can not delete it.
string *ps = new string("Hello ");
The new in the above statement is called new operator which do two things
Call operator new(allocates
necessary memory like malloc) and
Call constructor
on raw memory created by operator
new to initialize
delete ps;
Again delete corresponds to
Destruction of object and
Deallocation of memory(i.e, free)
In c++ user is not allowed to call constructor directly,Placement new is used when you have raw memory allocated by some means and wanted to initialize the bits with constructor.Because the memory allocation process did not happen through operator new, delete cannot deallocate the memory.
void someCode()
{
char memory[sizeof(Fred)];//memory allocated on stack
void* p = memory;
Fred* f = new(p) Fred();//placement new
...
f->~Fred(); // Explicitly call the destructor for the placed object
}