从DLL中的函数返回时的堆腐败 [英] Heap corruption when returning from function inside a dll

查看:208
本文介绍了从DLL中的函数返回时的堆腐败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个类似以下原型的函数:

I have a function with a prototype like the following:

void function(std::string str);

在另一个加载和使用该DLL的程序的主函数中调用此函数。 >

This function is called in my main function in another program that loads and uses that dll.

function("some string value here");

从此函数返回时,我收到堆损坏错误:

When returning from this function I get heap corruption error:


Windows已经在program.exe中触发了断点。

Windows has triggered a breakpoint in program.exe.

这可能是由于堆的损坏,这表示
program.exe或其加载的任何DLL的错误。

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.

这可能是由于用户按F12而
程序.exe有焦点。

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 * 也解决了这个问题。

什么可能导致这个错误?如何解决?

Playing around with my code I noticed a few strange observations:
1. When length of the string passed in is less than 11 characters I get no errors, as soon as I add more characters the error appears.
2. When changing the type of parameter from std::string to std::string& the error disappears. The idea of passing reference came from here.
3. I've commented out the body of the function. The operations in there have nothing to do with the exception produced.
4. Changing parameter type from std::string to char* also solves the problem.
What could be causing this error? How do I solve it?

推荐答案

很可能,你看到崩溃是由于在Windows中,DLL有他们自己的私人堆栈。

Most likely, you're seeing crashes due to the fact that, in Windows, DLLs have their own private heap.

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

When you compiled your function, the compiler generated some code for std::string's destructor, to clean up its arguments. This code frees the allocated memory on the DLL heap. However, the application EXE also generates its own code for std::string's constructor, which allocates the code on the program heap. When you allocate on one heap and free on the other, undefined behavior occurs, and you crash.

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

As for why small strings don't trigger the bug - many std::string implementations inline small strings into the struct itself, to avoid heap overhead. When your string is small enough to fit, no memory allocation need take place, and thus it happens to appear to work... as long as you use the same STL version for both EXE and DLL, and the threshold for inlining never changes.

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

To avoid this issue, don't pass objects by value to DLLs (unless they are POD objects), and don't free an object in a different DLL or EXE than it was created in. Avoid passing STL or C++ library objects around as well, as their implementation may differ between different versions of the C++ compiler. Pass POD objects or C primitive types such as const char * instead.

这篇关于从DLL中的函数返回时的堆腐败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆