std::unique_ptr, virtual and missing virtual destructor = major pitfall


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…

Share

, ,

Les commentaires sont fermés.