【发布时间】:2013-05-24 13:30:57
【问题描述】:
C++ 类构造函数可以内联或不内联。但是,我发现了一个奇怪的情况,只有内联类构造函数才能避免 Visual Studio 内存崩溃。示例如下:
dll.h
class _declspec(dllexport) Image
{
public:
Image();
virtual ~Image();
};
class _declspec(dllexport) Testimage:public Image
{
public:
Testimage();
virtual ~Testimage();
};
typedef std::auto_ptr<Testimage> TestimagePtr;
dll.cpp
#include "dll.h"
#include <assert.h>
Image::~Image()
{
std::cout<<"Image is being deleted."<<std::endl;
}
Image::Image()
{
}
Testimage::Testimage()
{
}
Testimage::~Testimage()
{
std::cout<<"Geoimage is being deleted."<<std::endl;
}
dll库编译为动态库,静态链接到C++运行库(Multi-threaded Debug (/MTd))。运行该库的可执行程序如下:
int main()
{
TestimagePtr my_img(new Testimage());
return 0;
}
可执行程序将调用 dll 库并静态链接运行时库。我遇到的问题是在运行可执行程序时出现以下错误消息:
但是,当dll中的类构造函数被内联时,如下代码所示:
class _declspec(dllexport) Image
{
public:
Image();
virtual ~Image();
};
class _declspec(dllexport) Testimage:public Image
{
public:
Testimage()
{
}
virtual ~Testimage();
};
崩溃会消失。有人可以解释背后的原因吗?谢谢!顺便说一句,我使用的是VC2010。
编辑:以下情况也会触发同样的崩溃 .
情况1
int main()
{
//TestimagePtr my_img(new Testimage());
Testimage *p_img;
p_img = new Testimage();
delete p_img;
return 0;
}
【问题讨论】:
-
尝试使用 /Md 动态链接 CRT
-
你能暂时改变它并检查它是否有效吗?另外:你能告诉我为什么你必须静态链接它吗?我很好奇
-
我会尝试重现这个案例。同时你为什么认为 /Mt 更稳定?如您所见,事实并非如此。通过静态链接 CRT,您可以显式创建多个堆。一个在 dll 中,另一个在主机中。因此,在 dll 中分配内存并在主机中删除它会杀死您的应用程序。你所说的内联实际上不是内联。当您在标头中实现 ctor 并包含它时,您会将 ctor 带入主机堆,这就是它在这种情况下不会崩溃的原因
-
@Samuel 构造函数是否内联无关紧要:“只有”
new和delete使用相同的堆才是重要的。new一直在主机里,我不明白std::auto_ptr是从哪里拿来的。 -
你能提供它的来源吗?知道很有趣