How to delete void pointer?

本小妞迷上赌 提交于 2019-12-09 08:08:46

问题


Is there anything wrong when deleting an object like this in C++?

MyCls* c = new MyCls();
void* p = (void*)c;
delete (MyCls*)p;

回答1:


This as written is legal.

The cast back to MyCls* is critical. Without that, you will invoke undefined behavior--the MyCls destructor will not be called, and other problems may arise as well (such as a crash). You must cast back to the correct type.

Also note that this can be complicated if multiple inheritance is involved and multiple casts are used. Your casts must "match" in either direction.

If your code is structured such that you won't know the type at the time of destruction, give each deletable object a common base class with a virtual destructor. Then cast back to the base class before delete is called.




回答2:


The code is well-defined. Both casts are static casts, although it is good style to make this explicit (static_cast<void*>, etc.) instead of using C-style casts. The standard says that if a pointer to object is converted to a void pointer and back by static casts, it will keep its original value. Thus, your final delete expression shall have the same effect as delete c.

That being said, use of void* is often a code smell in C++.




回答3:


It is a good practice to set the pointers to nullptr after deletion, especially to avoid access violation / segfault in another thread / event handler.

auto c = new MyCls();
auto p = static_cast<void*>c;
delete static_cast<MyCls*>p;
p = nullptr;
c = nullptr;

It is even better to use smart pointers and avoid new/delete altogether.

{
    auto c = std::make_unique<MyCls>();
    auto p = static_cast<void*>(c.get());
    // no need to delete p
} // c will be released automatically during unwinding

In C++, explicit casts such as static_cast is preferred.

If ~MyCls() is non-trivial, it will be invoked because you cast p to MyCls*. Deleting a void* won't invoke the destructor, and that could lead to memory leak or other problems.




回答4:


Although this code is valid, it is not good practice.

As a general guideline, there shouldn't be news and deletes in the wild. Try to enforce a rule that only constructors can call new and only destructors can call delete will help you organize your code better.

If you are using C++11, always try std::shared_ptr and the like, this will do the above automatically for you.



来源:https://stackoverflow.com/questions/24772699/how-to-delete-void-pointer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!