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.