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

时间:2014-02-21 14:25:48

标签: c++ memory-management dll

在构建动态库(在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:< / p>

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,预先分配内存是不可能的,那么我的问题是如何处理这种情况? (除了使用静态库)谢谢。

1 个答案:

答案 0 :(得分:2)

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

这非常麻烦,特别是对于您的代码。因为您通过DLL中的值返回std :: string。这是在堆上分配的DLL使用的CRT副本。调用者需要再次释放此对象。但它使用不同的堆,并且不可能释放该对象。 KABOOM。

使用/ MD是一个很难的要求。这确保了每个模块使用相同的CRT副本,并且最终程序中只存在单个实现。只要它们使用相同的CRT版本构建,无论如何。