41

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

MyCls* c = new MyCls();
void* p = (void*)c;
delete (MyCls*)p;
Sam
  • 7,252
  • 16
  • 46
  • 65
user3277361
  • 519
  • 1
  • 4
  • 4
  • 16
    Casting a pointer to `void *` and then back to its original type is guaranteed to preserve its value. – David Schwartz Jul 16 '14 at 05:25
  • 3
    §5.2.9/13 "A value of type pointer to object converted to “pointer to cv void” and back, possibly with different cv-qualification, shall have its original value." – Tony Delroy Jul 16 '14 at 05:42
  • 6
    Why would you want to do this? – Jack Aidley Jul 16 '14 at 08:35
  • @Jack Aidley, because I wanted to use a C++ class in C, so it was necessary to use void pointer. – user3277361 Jul 16 '14 at 10:04
  • 4
    I think you should probably post a more detailed question outlining what you're doing and why because I _strongly_ suspect that you're doing it in a less than desirable way if that's the case. – Jack Aidley Jul 16 '14 at 12:41
  • @DavidSchwartz: However it doesn't say what the resulting value is. It says so explicitly for other conversions, like "An rvalue of type float can be converted to an rvalue of type double. The value is unchanged" – Engineer2021 Jul 16 '14 at 21:51

3 Answers3

75

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.

StilesCrisis
  • 15,972
  • 4
  • 39
  • 62
35

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++.

Brian Bi
  • 111,498
  • 10
  • 176
  • 312
0

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.

Earth Engine
  • 10,048
  • 5
  • 48
  • 78