Delete on already deleted object: behavior?

I am wondering what will happen if I try to delete on a pointer that has already been deleted or may not have been highlighted? I read two things: firstly, the delete will do some checks, and we don’t need to check if the pointer is null; and then, I read that this could lead to unknown behavior ..

I ask for this because I use some personal objects that contain Qt object attributes; I think Qt removes all the widgets associated with closing the window, but I'm not sure and still: if the soft fails before closing the window, we must delete all the objects manually.

So what would be the best solution? Something like that?

 if( my_object ) delete my_object; 

Can dangerous behavior be avoided?

+4
source share
6 answers

delete to already delete d is not a null pointer - undefined behavior - your program will most likely fail. You can safely use delete on a null pointer - this will give a non-op.

Thus, the real problem is not equal to delete on the null pointer. The real problem is here:

  ptr = new Something(); otherPtr = ptr; delete ptr; delete otherPtr; 

This can happen if you have multiple pointers to the same object, and this is pretty dangerous. Possible solutions:

  • use smart pointers (no delete in your code) or
  • has only one assigned pointer to control each object's lifetime and delete at the right time.
+14
source
 if( my_object ) delete my_object; 

is redundant. delete on a NULL pointer does nothing. This is guaranteed by the standard.

delete on an already deleted pointer causes undefined behavior. This is why you should always remember to assign your pointers to NULL after they are removed:

 delete p; p = NULL; 

EDIT: According to the comments, I feel I have to indicate this. If you have multiple pointers to the same object, assigning NULL will not make the deletion safe. Despite this, it is better to use smart pointers.

+4
source

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 does nothing; deleting an already deleted object will result in undefined behavior.

+1
source

the right way:

 if( my_object ) { delete my_object; my_object = NULL; } 

because when called twice, as before, delete is called with the deleted pointer.

+1
source

This results in Undefined Behavior if you call delete on an already delete d-pointer.
Calling delete in a NULL pointer has no effect.

C ++ 03 standard § 3.7.4.2-3

If the release function completes by throwing an exception, the behavior is undefined. The value of the first argument passed to the release function may be the value of a null pointer; if so, and if the release function is included in the standard library, the call does not work. Otherwise, the specified value to the delete(void*) operator in the standard library must be one of the values ​​returned by the previous call to any new(std::size_t) or operator new(std::size_t, const std::nothrow_-t&) in the standard library, and the value provided to the delete[](void*) operator in the standard library must be one of the values ​​returned by the previous call either operator new[](std::size_t) or operator new[](std::size_t, const std::nothrow_t&) in the standard library.

Using RAII and smart pointers is your best weapon to avoid such problems.

0
source

Just to combine the answers above:

  • if (my_object) checks the value of the pointer, not the existence of the object. If it has already been deleted, the pointer may still point to this location.
  • Deleting an already deleted object is undefined behavior and is likely to cause your program to crash.
  • Removing NULL is defined and does nothing. Together with paragraph 1, this explains Lucian's answer.

To summarize: you must clearly understand who owns the object and where the pointer to the object is located. When you delete an object, make sure that all pointers pointing to this place are 0 / NULL. Use object management such as boost :: shared_pointer or QPointer to help you in this task.

0
source

Source: https://habr.com/ru/post/1386268/


All Articles