【问题标题】:Crash happens when Multi-threaded Debug (/MTd) is set (C++)设置多线程调试 (/MTd) 时发生崩溃 (C++)
【发布时间】:2014-03-23 02:58:31
【问题描述】:

在构建动态库(在 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&lt;int&gt; 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&lt;std::vector&lt;int&gt; &gt; myContainer, 分配内存,那么我的问题是如何处理这种情况? (使用静态库除外)谢谢。

【问题讨论】:

    标签: c++ memory-management dll


    【解决方案1】:

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

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-03
      • 1970-01-01
      • 1970-01-01
      • 2012-08-06
      相关资源
      最近更新 更多