In C++, whats the recommended way of deleting a pointer? For example, in the following case, do I need all three lines to delete the pointer safely (and if so, what do they do)?
// Create
MyClass* myObject;
myObject = new MyClass(myVarA, myVarB, myVarC);
// Use
// ...
// Delete
if(myObject) {
delete myObject;
myObject = NULL;
}
No you do not need to check for NULL.
delete takes care if the pointer being passed is NULL.
delete myObject;
myObject = NULL;
is sufficient.
As a general policy, avoid using freestore allocations wherever you can, and if you must use Smart Pointers(RAII) instead of raw pointers.
C++03 Standard Section §3.7.3.2.3:
The value of the first argument supplied to one of the deallocation functions provided in the standard library may be a null pointer value; if so, the call to the deallocation function has no effect. Otherwise, the value supplied to operator delete(void*) in the standard library shall be one of the values returned by a previous invocation of either operator new(size_t) or operator new(size_t, const std::nothrow_t&) in the standard library, and the value supplied to operator delete in the standard library shall be one of the values returned by a previous invocation of either operator new or operator new[](size_t, const std::nothrow_t&) in the standard library.
No, you don't need that.
Just write delete p, and be sure to not accept advice about anything else from anyone advocating that you do more.
General advice: avoid raw new and delete. Let some standard container deal with allocation, copying and deallocation. Or use a smart-pointer.
Cheers & hth.,
Best to use a resource-managing class and let the library take care of that for you:
#include <memory>
void foo() // unique pointer
{
std::unique_ptr<MyClass> myObject(new Myclass(myVarA, myVarB, myVarC));
// ...
} // all clean
void goo() // shared pointer -- feel free to pass it around
{
auto myObject = std::make_shared<MyClass>(myVarA, myVarB, myVarC);
// ...
} // all clean
void hoo() // manual -- you better know what you're doing!
{
MyClass * myObject = new MyClass(myVarA, myVarB, myVarC);
// ...
delete myObject; // hope there wasn't an exception!
}
Just to add that setting the pointer to NULL after it's been delete'd is a good idea so you don't leave any dangling pointers around since attempts to dereference a NULL pointer is likely to crash your application straight away (and so be relatively easy to debug), whereas dereferencing a dangling pointer will most likely crash your application at some random point and be much more difficult to track down and fix.
Related
Suppose I have the following code:
void* my_alloc (size_t size)
{
return new char [size];
}
void my_free (void* ptr)
{
delete [] ptr;
}
Is this safe? Or must ptr be cast to char* prior to deletion?
Deleting via a void pointer is undefined by the C++ Standard - see section 5.3.5/3:
In the first alternative (delete
object), if the static type of the
operand is different from its dynamic
type, the static type shall be a base
class of the operand’s dynamic type
and the static type shall have a
virtual destructor or the behavior is
undefined. In the second alternative
(delete array) if the dynamic type of
the object to be deleted differs from
its static type, the behavior is
undefined.
And its footnote:
This implies that an object cannot be
deleted using a pointer of type void*
because there are no objects of type
void
.
It depends on "safe." It will usually work because information is stored along with the pointer about the allocation itself, so the deallocator can return it to the right place. In this sense it is "safe" as long as your allocator uses internal boundary tags. (Many do.)
However, as mentioned in other answers, deleting a void pointer will not call destructors, which can be a problem. In that sense, it is not "safe."
There is no good reason to do what you are doing the way you are doing it. If you want to write your own deallocation functions, you can use function templates to generate functions with the correct type. A good reason to do that is to generate pool allocators, which can be extremely efficient for specific types.
As mentioned in other answers, this is undefined behavior in C++. In general it is good to avoid undefined behavior, although the topic itself is complex and filled with conflicting opinions.
It's not a good idea and not something you would do in C++. You are losing your type info for no reason.
Your destructor won't be called on the objects in your array that you are deleting when you call it for non primitive types.
You should instead override new/delete.
Deleting the void* will probably free your memory correctly by chance, but it's wrong because the results are undefined.
If for some reason unknown to me you need to store your pointer in a void* then free it, you should use malloc and free.
Deleting a void pointer is dangerous because destructors will not be called on the value it actually points to. This can result in memory / resource leaks in your application.
If you really must do this, why not cut out the middle man (the new and delete operators) and call the global operator new and operator delete directly? (Of course, if you're trying to instrument the new and delete operators, you actually ought to reimplement operator new and operator delete.)
void* my_alloc (size_t size)
{
return ::operator new(size);
}
void my_free (void* ptr)
{
::operator delete(ptr);
}
Note that unlike malloc(), operator new throws std::bad_alloc on failure (or calls the new_handler if one is registered).
The question makes no sense. Your confusion may be partly due to the sloppy language people often use with delete:
You use delete to destroy an object that was dynamically allocated. Do do so, you form a delete expression with a pointer to that object. You never "delete a pointer". What you really do is "delete an object which is identified by its address".
Now we see why the question makes no sense: A void pointer isn't the "address of an object". It's just an address, without any semantics. It may have come from the address of an actual object, but that information is lost, because it was encoded in the type of the original pointer. The only way to restore an object pointer is to cast the void pointer back to an object pointer (which requires the author to know what the pointer means). void itself is an incomplete type and thus never the type of an object, and a void pointer can never be used to identify an object. (Objects are identified jointly by their type and their address.)
Because char has no special destructor logic. THIS won't work.
class foo
{
~foo() { printf("huzza"); }
}
main()
{
foo * myFoo = new foo();
delete ((void*)foo);
}
The d'ctor won't get called.
A lot of people have already commented saying that no, it's not safe to delete a void pointer. I agree with that, but I also wanted to add that if you're working with void pointers in order to allocate contiguous arrays or something similar, that you can do this with new so that you'll be able to use delete safely (with, ahem, a little of extra work). This is done by allocating a void pointer to the memory region (called an 'arena') and then supplying the pointer to the arena to new. See this section in the C++ FAQ. This is a common approach to implementing memory pools in C++.
If you want to use void*, why don't you use just malloc/free? new/delete is more than just memory managing. Basically, new/delete calls a constructor/destructor and there are more things going on. If you just use built-in types (like char*) and delete them through void*, it would work but still it's not recommended. The bottom line is use malloc/free if you want to use void*. Otherwise, you can use template functions for your convenience.
template<typename T>
T* my_alloc (size_t size)
{
return new T [size];
}
template<typename T>
void my_free (T* ptr)
{
delete [] ptr;
}
int main(void)
{
char* pChar = my_alloc<char>(10);
my_free(pChar);
}
There is hardly a reason to do this.
First of all, if you don't know the type of the data, and all you know is that it's void*, then you really should just be treating that data as a typeless blob of binary data (unsigned char*), and use malloc/free to deal with it. This is required sometimes for things like waveform data and the like, where you need to pass around void* pointers to C apis. That's fine.
If you do know the type of the data (ie it has a ctor/dtor), but for some reason you ended up with a void* pointer (for whatever reason you have) then you really should cast it back to the type you know it to be, and call delete on it.
I have used void*, (aka unknown types) in my framework for while in code reflection and other feats of ambiguity, and so far, I have had no troubles (memory leak, access violations, etc.) from any compilers. Only warnings due to the operation being non-standard.
It perfectly makes sense to delete an unknown (void*). Just make sure the pointer follows these guidelines, or it may stop making sense:
1) The unknown pointer must not point to a type that has a trivial deconstructor, and so when casted as an unknown pointer it should NEVER BE DELETED. Only delete the unknown pointer AFTER casting it back into the ORIGINAL type.
2) Is the instance being referenced as an unknown pointer in stack bound or heap bound memory? If the unknown pointer references an instance on the stack, then it should NEVER BE DELETED!
3) Are you 100% positive the unknown pointer is a valid memory region? No, then it should NEVER BE DELTED!
In all, there is very little direct work that can be done using an unknown (void*) pointer type. However, indirectly, the void* is a great asset for C++ developers to rely on when data ambiguity is required.
If you just want a buffer, use malloc/free.
If you must use new/delete, consider a trivial wrapper class:
template<int size_ > struct size_buffer {
char data_[ size_];
operator void*() { return (void*)&data_; }
};
typedef sized_buffer<100> OpaqueBuffer; // logical description of your sized buffer
OpaqueBuffer* ptr = new OpaqueBuffer();
delete ptr;
For the particular case of char.
char is an intrinsic type that does not have a special destructor. So the leaks arguments is a moot one.
sizeof(char) is usually one so there is no alignment argument either. In the case of rare platform where the sizeof(char) is not one, they allocate memory aligned enough for their char. So the alignment argument is also a moot one.
malloc/free would be faster on this case. But you forfeit std::bad_alloc and have to check the result of malloc. Calling the global new and delete operators might be better as it bypass the middle man.
Assume I have a pointer void* p, then after some passing in and out of functions, let's say p is now pointing to int. Then do I need to manually delete as delete static_cast<int*>(p)?
In most places people say delete only happen when there is new. But in this case, it's not but does C++ itself remember to release that memory?
That all depends on how the int you're pointing to was allocated, you only delete what you new.
Correct (the int is new'd):
int* a = new int;
void* p = a;
//somewhere later...
delete static_cast<int*>(p);
Bad (the int is automatically managed):
int a = 0;
void* p = &a;
//somewhere later...
delete static_cast<int*>(p);
Answering the comment code, doing:
int* a = new int;
void* p = a;
delete p;
Is never okay. You should never delete through a void*, it's undefined behavior.
side note : in modern C++ you really shouldn't be using new or delete, stick with smart pointers or standard containers.
The short answer is: "It depends".
In most places people say delete only happen when there is new.
That's true so far as it goes. To avoid wasting resources and to ensure all destructors are called correctly every new has to be balanced by a delete somewhere. If your code can follow several paths you have to make sure that every path calls delete (if calling delete is appropriate).
The can get tricky when exceptions are thrown which is one reason why Modern C++ programmers generally avoid using new and delete. Instead they use the smart pointers std::unique_ptr and std::shared_ptr along with the helper template functions std::make_unique<T> and std::make_shared<T> (see the SO question: What is a smart pointer and when should I use one?) to implement a technique known as RAII (Resource Acquisition Is Instantiation).
But in this case, it's not …
Remember that the phrase ... when there is a new refers to the object the pointer points to not the pointer itself. Consider the following code...
int *a = new int();
void *p = a;
if (SomeTest())
{
delete a;
}
else
{
a = nullptr;
}
// This line is needed if SomeTest() returned false
// and undefined (dangerous) if SomeTest() returned true
delete static_cast<int *> (p);
Is that last line of code needed?
The object that a and p both point to was created by calling new so delete has to be called on something. If the function SomeTest() returned false then a has been set to nullptr so calling delete on it won't affect the object we created. Which means we do need that last line of code to properly delete the object that was newed up in the first line of code.
On the other hand, if the function SomeTest() returned true then we've already called delete for the object via the pointer a. In that case the last line of code is not needed and in fact may be dangerous.
The C++ standard says that calling delete on an object that has already been deleted results in "undefined behaviour" which means anything could happen. See the SO question: What happens in a double delete?
does C++ itself remember to release that memory?
Not for anything created by calling new. When you call new you are telling the compiler "I've got this, I will release that memory (by calling delete) when appropriate".
do I need to manually delete
Yes: if the object pointed to needs to be deleted here and the void * pointer is the only pointer you can use to delete the object.
I am wondering what will hapen if I try to do a delete on a pointer that is already deleted, or may have not been allocated ? I've read two things : first, that delete operator will do some checkings and we do not need to check if the pointer is null ; and then, I read that it can lead to unknown behaviors..
I'm asking it, because I use some personal objects that contains Qt objects attributes ; I think that Qt delete all widgets associated when we close the window, but I'm not pretty sure and still : if the soft crash before the window's close, we have to delete all objects manually.
So, what would be the best solution ? Something like that ?
if( my_object )
delete my_object;
Can it avoid dangerous behaviours ?
delete on an already deleted non-null pointer is undefined behavior - your program will likely crash. You can safely use delete on a null pointer - it will yield a no-op.
So the real problem is not delete on a null pointer. The real problem is here:
ptr = new Something();
otherPtr = ptr;
delete ptr;
delete otherPtr;
This can happen if you have several pointers to the same object and it is quite dangerous. The possible solutions are:
use smart pointers (no delete in your code) or
only have one designated pointer for controlling each object lifetime and delete at exactly the right time.
if( my_object )
delete my_object;
is redundant. delete on a NULL pointer does nothing. This is guaranteed by the standard.
delete on a pointer that was already deleted causes undefined behavior. That's why you should always remember to assign your pointers to NULL after you delete them:
delete p;
p = NULL;
EDIT: As per the comments, I feel I should specify this. If you have multiple pointers to the same object, the assignment to NULL won't make the delete safe. Regardless, it's better to use smart pointers.
Please note that deleting a pointer does not set it to NULL.
int* i = new int;
*i = 42;
delete i;
delete i; // oops! i is still pointing to the same memory, but it has been deleted already
Deleting a null pointer doesn't do anything, deleting an already deleted object will result in undefined behaviour.
the right way is:
if( my_object )
{
delete my_object;
my_object = NULL;
}
because, calling twice the way it was before will call delete on a deleted pointer.
It results in Undefined Behavior if you call delete on already deleted pointer.
Calling delete on a NULL pointer has no-effect though.
Standard c++03 § 3.7.4.2-3
If a deallocation function terminates by throwing an exception, the behavior is undefined. The value of the first argument supplied to a deallocation function may be a null pointer value; if so, and if the deallocation function is one supplied in the standard library, the call has no effect. Otherwise, the value supplied
to operator delete(void*) in the standard library shall be one of the values returned by a previous invocation of either operator new(std::size_t) or operator new(std::size_t, const std::nothrow_-t&) in the standard library, and the value supplied to operator delete[](void*) in the standard library shall be one of the values returned by a previous invocation of either operator new[](std::size_t) or
operator new[](std::size_t, const std::nothrow_t&) in the standard library.
Using RAII & Smart Pointers are your best weapons to avoid such problems.
Just to combine the answers above:
if (my_object) checks the value of the pointer, not the existence of the object. If it is already deleted, the pointer may still point to that location.
deleting an already deleted object is undefined behavior and will probably crash your program.
deleting NULL is defined and does nothing. Together with point 1 this explains the answer of Luchian.
To sum it up: You have to be clear on who owns the object and where the different pointer to the object are. When you delete an object, make sure to set all pointer pointing to that location to 0/NULL. Use managing objects like boost::shared_pointer or QPointer to help you in this task.
I was wondering if it is possible to add code (checks of the validity of the object pointed to actually) when a pointer is dereferenced.
I saw many subjects on overloading operator ->, but it seems the operator was called on an object, not a pointer. Maybe (probably) there is something I'm misunderstanding.
here's an example :
T* pObj = new T();
pObj->DoStuff(); // call check code (not in DoStuff)
delete pObj;
pObj->DoOtherStuff(); // call check code (not in DoOtherStuff)
the "check code" should be independent from the function (or members) called. My idea was to set a member as an int in the class, and give it a defined value at construction (and destruction), then check the value.
As you may have guess I try to check for invalid pointers used. I try to read the code but it's far too big and complex to not miss many potential errors.
Thanks for your answers and insights.
operator-> can only be overloaded as a member function of a class, not for a normal pointer.
In general there is no way to check that a (non-null) pointer actually points to a valid object. In your example delete pObj; does nothing to change the pointer; it just leaves it pointing to invalid memory, and there is no way to test for that. So, even if you could overload operator-> here, the best it could do is check that it wasn't null.
The usual approach is to use smart pointers, rather than normal pointers. A smart pointer is a class that wraps a plain pointer to an object, and has overloads of operator* and operator-> so that it looks and feels like a pointer. You won't delete the object directly, but through the pointer (when it goes out of scope, or explicitly by calling a reset() function), and the pointer can then set its plain pointer to null when that happens. In that way, the plain pointer will always be either valid, or null, so the overloaded operators can usefully check it before dereferencing.
Smart pointers (and RAII in general) bring other advantages too: automatic memory management, and exception safety. In your code, there will be a memory leak if DoStuff() throws an exception; pObj will go out of scope, and so there will be no way to access it to delete the object it points to. The memory will be lost and, if this keeps happening, you will eventually use all the system's memory and either crash or slow to a crawl. If it were a smart pointer, then the object would be deleted automatically as it went out of scope.
Commonly used smart pointers from the Standard Library and Boost are auto_ptr, scoped_ptr and shared_ptr, each with different behaviour when copying the pointer. C++0x will introduce unique_ptr to replace auto_ptr.
You should overload operators -> and *, in more or less the same way that auto_ptr works.
For example:
template<typename T>
class SafePtr {
public:
SafePtr(T*p) : ptr(p) {}
T &operator*()
{
if ( !preConditions() ) {
throw runtime_error( "preconditions not met" );
}
return *ptr;
}
T * operator->()
{
if ( !preConditions() ) {
throw runtime_error( "preconditions not met" );
}
return ptr;
}
bool preConditions()
{ return ( ptr != NULL ); }
private:
T* ptr;
};
This could be a very basic example. The -> operator would be overloaded in a similar way. All the logic you want to execute before dereferencing the pointer would be coded inside preConditions(). I think that you can get the idea from here, if not, you can ask further.
Hope this helps.
operator -> (or any other operators) can be overloaded only for class objects and not for pointers. For your case, you can think of using standard/cutom Smart Pointers (which are actually objects and not pointer, but they can be used as of they are pointers).
If can not use smart pointers, then make a practice of assigning NULL after delete/free. Or you can use your custom wrapper for delete such as:
template<typename T>
void Destroy (T *&p) // use this wrapper instead of 'delete'
{
delete p;
p = 0;
}
As Nick already pointed out, use std::auto_ptr or better (and if possible) boost::shared_ptr. It basically implements almost exactly what you want.
To answer the question directly: indeed, you can only overload operator-> for a class, so in that case you won't be able to apply it to a pointer of that class. In other words, it will apply to objects, not pointers.
class T {
T& operator->() { }
};
void f() {
T* pObj = new T();
pObj->DoStuff(); // Calls DoStuff, but... Oops! T::operator->() was not called!
(*pObj).DoStuff(); // Equivalent to the above
delete pObj;
(*pObj)->DoStuff(); // T::operator->() is called, but
// there is no improvement here: the pointer is dereferenced
// earlier and since it was deleted, this will "crash" the application
//pObj->->DoStuff(); // Syntactically incorrect, but semantically equivalent
//to the above
pObj->operator->()->DoStuff(); // Semantically equivalent to the above two,
//but avoids the double member access operator.
}
in the following code:
class x
{
private:
someRef& m_ref;
public:
x(someRef& someRef):m_ref(someRef)
{
}
do I need to do:
~x()
{
delete m_ref;
}
which by the way doesnt work without getting the pointer...
basically I'm asking: Do I need to call a destructor on a reference member?
No.
You only need to delete an object if you own it. If you were passed a reference, it means that someone else owns it, thus it's unnecessary and thankfully the language prevents it.
I don't think one actually strictly speaking ever deletes even pointers. What you delete are dynamically allocated objects (or arrays of objects) that the pointer is a handle for. If the object originates from a call to new and it is the responsibility of this class to clean up after this object, then you call delete.
It is technically possible that a reference might be referring to a dynamically allocated object:
int main()
{
//in principle a reference can also refer to a dynamically allocated object
x var(*new someRef);
}
//and if that is the intended usage:
x::~x()
{
delete &m_ref;
}
However, this would be incredibly bad style. By convention, the "owning" handle of a dynamically allocated object should not be a reference.
No. You can only delete pointers, not references, and even then you must only delete objects that you allocated using the new operator. And then you must be sure to delete them only once. Here is the case in which you would need to use delete in your destructor:
class x
{
private:
someObj* m_ptr;
public:
x():m_ptr(new someObj())
{
}
~x()
{
delete m_ptr;
}
But in general it's best to avoid even this and use smart pointers instead.
I want to clarify some misconceptions you seem to have that are beyond the intent of your question:
When a class's destructor is called all of it's members' destructors get called as well.
Calling delete is not the same as calling the destructor. delete explicitly calls the destructor and also calls operator delete at the objects location, it is a 2 part thing.
For a small bit of extra clarification I want to offer the following:
int *pi = new int;
//int& ir = pi; // can't do
// this a reference to the pointer but it is an error
// because or the type difference int& vs int* and
// static_cast won't help. reinterpret_cast would allow
// the assignment to take place but not help the 'delete ir'
int& ir = *pi; // this is OK - a reference to what the pointer points to.
// In other words, the the address of the int on the heap.
//delete ir; // can't do, it is a reference and you can't delete non-pointers.
delete &ir; // this works but it is still not "deleting a reference".
// The reference 'ir' is another name for the heap-based int.
// So, &ir is the address of that int, essentially a pointer.
// It is a pointer that is being used by delete, not a reference.