Is deleting a pointer same as freeing a pointer (that allocates the memory)?
Deleting a pointer (or deleting what it points to, alternatively) means
delete p;
delete[] p; // for arrays
p was allocated prior to that statement like
p = new type;
It may also refer to using other ways of dynamic memory management, like free
free(p);
which was previously allocated using malloc or calloc
p = malloc(size);
The latter is more often referred to as "freeing", while the former is more often called "deleting". delete is used for classes with a destructor since delete will call the destructor in addition to freeing the memory. free (and malloc, calloc etc) is used for basic types, but in C++ new and delete can be used for them likewise, so there isn't much reason to use malloc in C++, except for compatibility reasons.
You can't "delete" a pointer variable
Sure you can ;-)
int** p = new int*(new int(42));
delete *p;
delete p; // <--- deletes a pointer
But seriously, delete should really be called delete_what_the_following_pointer_points_to.
Yes, delete is used to deallocate memory and call the destructor for the object involved.
It's common pratice to set pointer to NULL after deleting it to avoid having invalid pointers around:
Object *o = new Object();
// use object
delete o; // call o->~Object(), then releases memory
o = NULL;
When new and delete are used with standard C types in C++ source they behave like malloc and free.
You can't "delete" a pointer variable, only set their value to NULL (or 0).
Yes deleting a pointer is the same as deallocating memory or freeing memory, etc.
Yes and it calls the appropriate destructor.
In short, yes.
But you have to be careful: if you allocate with p = new sometype() only then should you use delete p. If you allocate using p = sometype[count] always use delete [] p
And one more thing: you should never pair malloc/delete or new/free.
Related
Must I use operator delete for stack pointer?
For example:
User * p = new User;
delete p; //needed?
When you use delete you are not deleting the pointer, so it makes no difference whether it is a stack pointer or any other kind of pointer.
When you use delete you are deleting the block of memory pointed by the pointer. If that block was allocated with new, then it's always on the heap. (If it was not allocated with new, then you should not delete it.)
The other angle is that no, you must not use operator delete, because you should never use naked pointers in non-library code.
In modern C++, your example should be:
std::unique_ptr<User> p = std::make_unique<User>();
No delete and no new in sight.
Note: in this particulate case, make_unique could be substituted for new painlessly, but since in other examples it might not be, it's a good practice to teach yourself - make_unique is a function to use.
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/
I have a class pointer declaration:
MyClass* a;
In destruction method I have:
if (a)
{
delete a;
a= NULL;
}
I got a problem when delete the pointer a:
Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
What is the cause of the problem and how can I get rid of it?
With your current declaration:
MyClass* a;
a gets a random value. If you never give it a valid value later, such as:
a = new MyClass();
It will point to an unknown place in memory, quite probably not a memory area reserved for your program, and hence the error when you try to delete it.
The easiest way to avoid this problem is to give a a value when you declare it:
MyClass* a = new MyClass();
or, if you cannot give it a value when you declare it (maybe you don't know it yet), assign it to null:
MyClass* a = 0;
By the way, you can remove the test (if (a)) from your code. delete is a no-op on a null pointer.
Use smart pointer to free memory. delete in application code is always wrong.
unless you have initialized the pointer to something after this:
MyClass* a;
the pointer a will hold some random value. So your test
if (a) { }
will pass, and you attempt to delete some random memory location.
You can avoid this by initializing the pointer:
MyClass* a = 0;
Other options are that the object pointed to has been deleted elsewhere and the pointer not set to 0, or that it points to an object that is allocated on the stack.
As has been pointed out elsewhere, you could avoid all this trouble by using a smart pointer as opposed to a bare pointer in the first place. I would suggest having a look at std::unique_ptr.
How did you allocate the memory that a points to? If you used new[] (in order to create an array of MyClass), you must deallocate it with delete[] a;. If you allocated it with malloc() (which is probably a bad idea when working with classes), you must deallocate it with free().
If you allocated the memory with new, you have probably made a memory management error somewhere else - for instance, you might already have deallocated a, or you have written outside the bounds of some array. Try using Valgrind to debug memory problems.
You should use
MyClass* a = NULL;
in your declaration. If you never instantiate a, the pointer is pointing to an undefined region of memory. When the containing class destructor executes, it tries to delete that random location.
When you do MyClass* a; you declare a pointer without allocating any memory. You don't initialize it, and a is not necessarily NULL. So when you try to delete it, your test if (a) succeeds, but deallocation fails.
You should do MyClass* a = NULL; or MyClass* a(nullptr); if you can use C++11.
(I assume here you don't use new anywhere in this case, since you tell us that you only declare a pointer.)
int* func()
{
int* i=new int[1];
//do something
return i;
}
void funcc()
{
int* tmp=func();
//delete allocated memory after use
delete tmp;
}
should delete working as described in the second function be a correct use ?
I think I didn't allocate memory to it by new ? new was used in the first, to be sure.
It should be delete [] tmp; because you're doing array new, but otherwise, it's correct.
As others have stated, you should use delete[] to delete arrays, not delete.
But, if you're asking whether it's okay to delete tmp because the memory it points to wasn't allocated with new, then your premise is incorrect.
It was allocated with new. The address of the memory that you allocate within the function for i is passed back to be stored in tmp, so it does point to memory that was allocated by new.
You're correct that i itself is out of scope at that point but memory allocated by new survives the scope change on exit from the function. And, since you're storing its location into tmp, you still have access to it.
Hence the deletion (once you make it an array deletion with []) is quite valid.
This is Undefined Behaviourâ„¢. You can only use delete if you used new. If you used new[], you MUST delete[] it. More than that, this is hideously unsafe code- you need a smart pointer.
No. new T[] should match delete []t. And new T should match delete t. Otherwise, your code would invoke undefined bevavior.
And it doesn't matter if you do delete []tmp outside the function. Its okay to do so. All that you need to keep in mind that the form of delete.
My spidey-senses tell me that you're wondering whether the dynamically-allocated int that you create in func is the same one that you attempt to delete in funcc.
The answer is: yes. Although you don't use strictly the same pointer variable, both pointers point to the same object.
However, please remember to use delete[] (with the []) when you used new[] (with the []). Your code is broken until you fix this.
Also, try to avoid newing in one place and deleteing in another. Perhaps consider a std::vector instead, which is far less error-prone.
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.