In our company, the build infrastructure runs unit tests in a valgrind shell, trying to detect memory leaks at the time the unit tests are executed. And every now and then, although our memory allocations are mostly handled through std::unique_ptr or std::shared_ptr, a leak pops up on the radar. And usually with the most useless trace valgrind can come up with. How can that be ?
The answer is in the title of this post: deleting an object without virtual destructor using a pointer to base results in slicing.
But wait ?! Isn’t there a warning for that ?
Try
Interface *p = new Implementation;
delete p;
and with -Wall at least, you get deleting object of abstract class type ‘Interface’ which has non-virtual destructor will cause undefined behaviour.
But try
std::unique_ptr p(new Implementation);
and you get strictly no warning.
If that’s not a pitfall, what is it ?!
Previous versions would warn you but the warning has been disabled from -Wall. It is still available as -Wnon-virtual-dtor. Using that one you get:
‘class Implementation’ has virtual functions and accessible non-virtual destructor. It can raise false positives but at least you will be warned !
Thanks to my colleague Lieven de Cock for finding this bastard laying in my code…