CodeSOD: Magical Destruction

Pretty much all object oriented languages have some concept of "destruction": objects need to release any resources they acquired at construction. In a lot of cases, we don't need to customize this terribly much, but when we do, it's vitally important to do it correctly.

Nancy's co-worker perhaps didn't understand the "correctly" part. So this was the standard pattern of C++ constructor that they wrote:

SomeObject::~SomeObject( )
{
  if (!this)
    delete this;
}

So, the first thing to point out is that this will always have a value at this point in the object's life-cycle. So the condition is never true, and thus this destructor does nothing, and we can safely ignore it.

But I can't just ignore it, because I'm trying to understand the thought process of this. The purpose of delete in C++ is to take memory referenced by a pointer and free it. If this is null (if that condition were true), then the pointer isn't pointing anywhere, thus there's nothing to delete. But the problem is only worse if we were to remove that conditional, because this is already in the process of being deleted. The lifecycle of that object is over, and thus we can't delete it- this is undefined behavior, and you all know what undefined behavior means in C or C++: nasal demons.

One tiny if that can never be true is all that saves the original developer from having demons fly out their nose.

All that said, it is easy to understand the developer's logic here: they picked up this code as an "incantation" at some point- magic words they need to include without understanding what they do. They just forever after repeated the incantation, like a spell, assuming it would ensure no memory leaks, a bountiful harvest, and appease the gods of C++ so that they do not rain down their fury on us all.

[Advertisement] Otter - Provision your servers automatically without ever needing to log-in to a command prompt. Get started today!

This post originally appeared on The Daily WTF.

Leave a Reply

Your email address will not be published. Required fields are marked *