Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CRT virtual destructor

I ran into a heap corruption today caused by different CRT settings (MTd MDd) in my dll and my actual project. What I found strange is that the application only crashed when I set the destructor in the dll to be virtual. Is there an easy explanation for that? I get that I can't free memory that's not on my heap, but where exactly is the difference when I define the destructor as non-virtual.

Some Code just to make it a little clearer

The DLL

#pragma once
class CTestClass
{
public:
    _declspec(dllexport) CTestClass() {};
    _declspec(dllexport) virtual ~CTestClass() {};
};

And my project

int main(int argc, char* argv[])
{
    CTestClass *foo = new CTestClass;
    delete foo; // Crashes if the destructor is virtual but works if it's not
}
like image 534
Poisonbox Avatar asked Jul 08 '13 16:07

Poisonbox


People also ask

What is a virtual destructor C++?

Virtual destructors in C++ are used to avoid memory leaks especially when your class contains unmanaged code, i.e., contains pointers or object handles to files, databases or other external objects. A destructor can be virtual.

When should you use a virtual destructor?

Virtual keyword for destructor is necessary when you want different destructors should follow proper order while objects is being deleted through base class pointer.

Is destructor virtual by default C++?

The destructor is not user-provided (meaning, it is either implicitly declared, or explicitly defined as defaulted on its first declaration) The destructor is not virtual (that is, the base class destructor is not virtual) All direct base classes have trivial destructors.

Should abstract class have virtual destructor?

The answer to your question is often, but not always. If your abstract class forbids clients to call delete on a pointer to it (or if it says so in its documentation), you are free to not declare a virtual destructor. You can forbid clients to call delete on a pointer to it by making its destructor protected.


1 Answers

There is a difference between

class CTestClass
{
public:
    _declspec(dllexport) CTestClass() {}
    _declspec(dllexport) virtual ~CTestClass() {}
};

and

__declspec(dllexport) class CTestClass
{
public:
     CTestClass() {}
     virtual ~CTestClass() {}
};

In the former case you instructed a compiler to export only two member functions: CTestClass::CTestClass() and CTestClass::~CTestClass(). But in the latter case you would instruct a compiler to export the table of virtual functions as well. This table is required once you have got a virtual destructor. So it might be the cause of the crash. When your program tries to call virtual destructor, it looks for it in the associated virtual functions table, but it is not initialized properly so we do not know where it really points then. If your destructor is not virtual, then you do not need any virtual function table and everything works just fine.

like image 60
Alan Milton Avatar answered Sep 30 '22 12:09

Alan Milton