简体   繁体   中英

c++ do I need to manually delete a void* pointer which is then pointing to another concrete type?

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 .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM