设置(C++)多线程调试(/MTd)时会发生崩溃



当构建动态库(在C++中)时,我们可以选择Windows的多线程调试(/MTd)或多线程调试DLL(/MDd)运行时库。如果我们选择"多线程调试",那么创建的动态库将负责为库中使用的所有变量分配内存。因此,以下示例将显示/MDd设置有效而/MTd设置失败的情况:

my_dll.h

class MY_EXPORT DllClass
{
public:
std::vector<int> abcWorkable;

void create_new_input_workable();
};

my_dll.cpp

void DllClass::create_new_input_workable()
{
abcWorkable.push_back(3);
abcWorkable.push_back(4);
}

main.cpp

int main(void)
{
DllClass mine;
//mine.abcWorkable.reserve(20);
mine.create_new_input_workable();       
return 0;
}

这个问题有两种解决方案:一种是使用静态库而不是动态库,另一种是只在动态库或可执行文件中分配内存,例如,如果我们更改main.cpp:

int main(void)
{
DllClass mine;
mine.abcWorkable.reserve(20);
mine.create_new_input_workable();       
return 0;
}

它将工作,因为这一次变量std::vector<int> abcWorkable在可执行程序中被分配了内存。但是,如果类内部的变量(在dll中)难以在可执行文件中分配内存,则此解决方案可能会失败。我还举了另一个例子:

my_dll.h

class MY_EXPORT DllClass
{
public:
std::list<std::vector<int> > myContainer;
void create_new_input();
}

my_dll.cpp

void DllClass::create_new_input()
{
std::vector<int> abc;
abc.push_back(2);
abc.push_back(3);
myContainer.push_back(abc);
}

main.cpp

int main()
{
DllClass mine;
mine.create_new_input();
std::list<std::vector<int> >::iterator it = mine.myContainer.begin();
std::list<std::vector<int> >::iterator itEnd = mine.myContainer.end();
while(it != itEnd)
{
for(int i=0; i<(*it).size(); i++)
std::cout<<(*it)[i]<<std::endl;
it++;
}
return 0;
}

不可能为变量std::list<std::vector<int> > myContainer,预先分配内存,那么我的问题是如何处理这种情况?(使用静态库除外)谢谢。

使用/MT构建时,每个模块都将拥有自己的CRT副本。具有自己的全局变量(如errno)和使用自己堆的内存分配器。最终程序将使用多个CRT副本运行。

这是非常麻烦的,尤其是您的代码。因为您从DLL中按值返回std::字符串。它是在DLL使用的CRT副本的堆上分配的。调用方需要再次释放此对象。但它使用了一个不同的堆,并且不可能释放该对象。卡博姆。

在这里,使用/MD是一项硬性要求。这确保了每个模块都使用相同的CRT副本,并且在最终程序中只有一个实现。只要它们是用相同的CRT版本建造的。

最新更新