c++ - 从 dll 中的函数返回时堆损坏

标签 c++ dll exception-handling heap-corruption

我有一个原型(prototype)如下的函数:

void function(std::string str);

这个函数在我的主函数中被另一个加载和使用该 dll 的程序调用。

function("some string value here");

从这个函数返回时我得到堆损坏错误:

Windows has triggered a breakpoint in program.exe.

This may be due to a corruption of the heap, which indicates a bug in program.exe or any of the DLLs it has loaded.

This may also be due to the user pressing F12 while program.exe has focus.

The output window may have more diagnostic information.

在研究我的代码时,我发现了一些奇怪的现象:
1.当传入的字符串长度小于11个字符时,我没有报错,一旦我添加更多字符,就会出现错误。
2. 将参数类型从 std::string 更改为 std::string& 时,错误消失。传递引用的想法来自 here .
3. 我已经注释掉了函数体。里面的操作与产生的异常无关。
4. 将参数类型从std::string 更改为char* 也解决了问题。
是什么导致了这个错误?我该如何解决?

最佳答案

您遇到崩溃的原因很可能是,在 Windows 中,DLL 有自己的私有(private)堆。

当您编译函数时,编译器会为 std::string 的析构函数生成一些代码,以清理其参数。此代码释放 DLL 堆上分配的内存。然而,应用程序 EXE 也会为 std::string 的构造函数生成自己的代码,它在程序堆上分配代码。当您在一个堆上分配并在另一个堆上释放时,会发生未定义的行为,并且您会崩溃。

至于为什么小字符串不会触发错误 - 许多 std::string 实现将小字符串内联到结构本身,以避免堆开销。当您的字符串足够小以适合时,不需要进行内存分配,因此它似乎可以正常工作……只要您对 EXE 和 DLL 使用相同的 STL 版本,并且内联的阈值永远不会改变。

为避免此问题,不要按值将对象传递给 DLL(除非它们是 POD objects ),并且不要在与创建对象不同的 DLL 或 EXE 中释放对象。避免传递 STL 或 C++库对象也是如此,因为它们的实现在不同版本的 C++ 编译器之间可能不同。改为传递 POD 对象或 C 基本类型,例如 const char *

关于c++ - 从 dll 中的函数返回时堆损坏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13679104/

相关文章:

c++ - -march=native 有害的原因是什么

C++ 将文件从资源复制到目录?

c++ - EXC_BAD_ACCESS 与 OSX 中的 wxWidgets

c# - pinvoke:结构在C端填充,但回到家后数据消失了

c++ - 如何在 C++ 中构建与运行时版本无关的 DLL?

python-2.7 - 如何拦截flask中的所有异常?

c++ - int 如何成为 AssetManager?

c++ - DLL注入(inject)。带参数执行CreateRemoteThread

c++ - c++ 中的 stdexcept 与异常 header

Java:如何在 try catch 体内向方法调用者抛出异常?