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

标签 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:

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::string。它被分配在 DLL 使用的 CRT 拷贝的堆上。该对象需要由调用者再次释放。但它使用不同堆并且不可能释放该对象。轰隆隆。

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

关于c++ - 设置多线程调试 (/MTd) 时发生崩溃 (C++),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21937079/

相关文章:

c++ - 将函数定义放在头文件中

java - 对象数组内存分配(堆栈和堆)

r - 在 R xgboost 包上拟合模型后,如何释放 GPU 内存?

c# - 需要加载一个 DLL 才能在 C# 中使用 SQLiteWrapper

c++ - Protocol Buffers with dll 编程 c++

c# - 如何将.Net3.5 dll 添加到.Net2.0 工程中?

c++ - 我的程序如何从 ASCII 切换到 Unicode?

c++ - 为什么我们在 C++ 中使用返回数据结构的函数?

c++ - 如何修复QT中的GL.h编译错误?

c++ - C++中未初始化的内存