调试失败!表达式:_pFirstBlock == pHead [英] Debug Assertion Failed! Expression: _pFirstBlock == pHead

查看:3292
本文介绍了调试失败!表达式:_pFirstBlock == pHead的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在调用静态链接的.dll,我看到此错误:

I am calling into a statically linked .dll, and I see this error:

我写了.dll和调用代码。不应该发生此错误。我想知道其他人是否曾经遇到过? .dll只包含大约10行代码,它只是一个测试.dll,看看dll如何工作。当我把一个std :: string传回.dll时,它就会爆炸。

I wrote both the .dll and the calling code. This error should not be occurring. I am wondering if anyone else has encountered it before? The .dll only contains about 10 lines of code, its just a test .dll to see how dlls work in general. It blows up when I pass a std::string back out of the .dll.

我使用Visual Studio 2012和C ++。

I am using Visual Studio 2012 and C++.

我将尝试下一步

调试声明... _pFirstBlock == pHead


如果在
多线程模块中使用单线程库,则会出现问题。

This problem can occur if one uses the single-threading libraries in a multithreaded module.

明天,我将尝试重新编译在多线程模式下的Boost静态库(我的.dll设置为多线程静态模式)。

Tomorrow, I'll try recompiling the Boost static libraries in multi-threaded mode (my .dll is set to multi-threaded static mode).

请参阅在导出的对象中使用字符串从DLL中导致运行时错误


你需要做两件事之一

You need to do one of two things


  1. 将DLL和使用它的客户端都链接到CRT的 版本(例如不静态)。

  2. 或者您需要确保不会跨DLL边界传递动态分配的内存(例如包含在字符串对象中)。
    换句话说,没有DLL导出的函数返回字符串
    对象。

  1. Make both the DLL and the client that use it both link to the DLL version of the CRT (e.g. not statically).
  2. OR You need to make sure you don't pass dynamically allocated memory (such as is contained in string objects) across DLL boundaries. In other words, don't have DLL-exported functions that return string objects.

Joe

这似乎匹配什么事情,它在我把一个字符串传递回一个.dll边界的精确点爆炸。这个问题只发生在一切都以静态模式链接的时候。现在可以修复了。

This seems to match whats going on, it blows up at the precise point where I pass a string back across a .dll boundary. The problem only occurs when everything is linked in static mode. Now that's fixable.

请参阅将传递给STL向量的引用传递到dll边界

我接下来要做什么
$ b

请参见无法将std :: wstring跨DLL

解决方案


推荐答案

在这种情况下,问题是我传递一个 std :: string

In this case, the problem is that I was passing a std::string back across a .dll boundary.


  • 如果MSVC 运行库设置为多线程调试DLL(/ MDd)

如果设置了MSVC 运行库多线程调试(/ MTd),那么它将抛出此错误,可通过以下指令修复。

If the MSVC Runtime library is set to Multi-threaded Debug (/MTd), then it will throw this error, which can be fixed with the following instructions.

问题是,内存分配在.dll端,那么同一内存在应用程序端释放。这意味着内存管理器A正在分配内存,而内存管理器B正在释放同一个内存,从而产生错误。

The problem is that memory is allocated on the .dll side, then that same memory is freed on the application side. This means that memory manager A is allocating memory, and memory manager B is releasing that same memory, which generates errors.

解决方案是确保所有内存传回是在DLL中分配的。换句话说,内存总是在应用程序端分配,并在应用程序端释放。

The solution is to make sure that all memory passed back is not allocated in the DLL. In other words, the memory is always allocated on the application side, and freed on the application side.

当然,DLL可以在内部分配/释放内存 -

Of course, the DLL can allocate/free memory internally - but it can't allocate memory that is later freed by the application.

这将不会分配应用程序释放的内存。 工作:

// Memory is allocated on the .dll side, and freed on the app side, which throws error.
DLL std::string GetString(); 

这将工作:

// Memory is allocated/freed on the application side, and never allocated in the .dll.
DLL int GetString(std::string& text); 

但这还不够。

在应用程序端,该字符串必须预先分配:

On the application side, the string has to be pre-allocated:

std::string text("");
text.reserve(1024);     // Reserves 1024 bytes in the string "text".

在.dll端,文本必须复制到原始缓冲区

On the .dll side, the text must be copied into the original buffer (rather than overwritten with memory that is allocated on the .dll side):

text.assign("hello");

有时候,C ++会坚持分配内存。请仔细检查预先分配是否仍然相同:

Sometimes, C++ will insist on allocating memory anyway. Double check that the pre-allocation is still the same as it was:

if (text.capacity < 1024)
{
   cout << "Memory was allocated on the .dll side. This will eventually throw an error.";
}

另一种方式是使用 std :: shared_ptr< std :: string> ,因此即使内存分配在.dll中,也是由.dll(而不是应用程序端)释放的。

Another way that works is to use std::shared_ptr<std::string>, so even though memory is allocated in the .dll, it is released by the .dll (rather than the application side).

另一种方法是接受 char * 和一个表示预分配内存量的长度。如果我们要传回的文本长度超过预先分配的内存长度,则返回错误。

Yet another way is to accept a char * and a length which indicates the amount of pre-allocated memory. If the text that we want to pass back is longer than the length of pre-allocated memory, return an error.

这篇关于调试失败!表达式:_pFirstBlock == pHead的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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