由于我的 dll 和我的实际项目中的不同 CRT 设置 (MTd MDd),我今天遇到了堆损坏。 我发现奇怪的是,只有当我将 dll 中的析构函数设置为虚拟时,应用程序才会崩溃。 对此有一个简单的解释吗?我知道我无法释放不在我的堆上的内存,但是当我将析构函数定义为非虚拟时,究竟有什么不同。
一些代码只是为了让它更清晰一些
动态链接库
#pragma once
class CTestClass
{
public:
_declspec(dllexport) CTestClass() {};
_declspec(dllexport) virtual ~CTestClass() {};
};
还有我的项目
int main(int argc, char* argv[])
{
CTestClass *foo = new CTestClass;
delete foo; // Crashes if the destructor is virtual but works if it's not
}
最佳答案
有区别
class CTestClass
{
public:
_declspec(dllexport) CTestClass() {}
_declspec(dllexport) virtual ~CTestClass() {}
};
和
__declspec(dllexport) class CTestClass
{
public:
CTestClass() {}
virtual ~CTestClass() {}
};
在前一种情况下,您指示编译器仅导出两个成员函数:CTestClass::CTestClass() 和 CTestClass::~CTestClass()。但在后一种情况下,您会指示编译器也导出虚函数表。一旦你有一个虚拟析构函数就需要这个表。所以这可能是崩溃的原因。当你的程序试图调用虚析构函数时,它会在相关的虚函数表中寻找它,但它没有正确初始化,所以我们不知道它真正指向哪里。如果您的析构函数不是虚拟的,那么您就不需要任何虚函数表,一切正常。
关于c++ - CRT虚拟析构函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17531558/