I came across a strange use of the destructor while working on an existing library. The destructor of a stack allocated stl vector was being called explicitly, when its the case that that object may need to be used again. These vector objects are a slightly customised version of the stl vector class that have a specialized clear
method. In the destructor body there exist two method calls: clear()
, _Tidy()
.
I've been trying to think of a good reason why this destructor is being called rather than just clear
but I'm at a loss. Anyone shed any light on why this may be a good idea?
Large vector?
Wild guess... when
clear()
is called the vector is usually emptied but the memory not released. That is why there's the patternto empty the vector for reuse and clear the allocated memory.
Perhaps the original author did not know the pattern and tried to get rid of the allocated memory in this wicked fashion. (I think
_Tidy
frees the allocated memory)Maybe the original coder cared about where in memory the objects were allocated.
Then the destructor must be called explicitly, as per this discussion.
Could this class use some kind of placement new method? That's the only time I tend to see explicit destructors in use.
It's definitely not a good idea. Any operation on an object after the destructor starts running yields undefined behavior.
clear() isn't guaranteed to actually release the allocated storage in the vector; _Tidy() in the MSVC implementation will actually free that storage, so this was probably done as an optimization.
It's an evil thing to do, but you can do it legally (without undefined behavior) so long as the storage is reused by an object of the same type (ignoring cv-qualifiers) that takes up exactly all of the storage:
Section 3.8.7 of the C++ standard describes this usage scenario and explains how it's legal; it even includes an example that is similar to the above.