Debug Assertion Failed! Expression: _pFirstBlock == pHead

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

If the MSVC Runtime library is set to Multi-threaded Debug DLL (/MDd), then this is no problem (it works fine).

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.

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.

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.

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

This will not work:

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

This will work:

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

However, this is not quite enough.

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

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

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");

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.";
}

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).

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.

以上原文转自:http://stackoverflow.com/questions/18882760/debug-assertion-failed-expression-pfirstblock-phead

翻译:这种情况是由于跨越.dll传递std::string造成的。

如果MSVC Runtime library设定为Multi-threaded Debug DLL (/MDd),这个问题不会出现。

如果MSVC Runtime library设定为Multi-threaded Debug (/MTd),则会出现这个问题。

遵循以下步骤可以修复这个问题。

问题出在内存在.dll一边被开辟,而却在application一边却被释放。这意味着A开辟了内存,而B却要释放A开辟的内存,这样就产生了错误。

DLL可以在它内部开辟/释放内存,但是它不可以开辟一个稍后会被application释放的内存空间。

这个不可以:

// Memory is allocated on the .dll side, and freed on the app side, which throws error.
// 内存在.dll中开辟,在application中释放,报错。
DLL std::string GetString(); 
这个可以:

// Memory is allocated/freed on the application side, and never allocated in the .dll.
// 内存在application中开辟和释放,没有在.dll中开辟。
DLL int GetString(std::string& text); 
然而,还不够好。

在application一边,字符串应该被预创建。

std::string text("");
text.reserve(1024);     // Reserves 1024 bytes in the string "text".
在.dll一边,文本应该被拷贝到原始缓存中(而不是在.dll中复写内存)

text.assign("hello");
有的时候,C++会坚持去开辟内存,因此需要做双检查。

if (text.capacity < 1024)
{
   cout << "Memory was allocated on the .dll side. This will eventually throw an error.";
}
另外一个解决方案是使用:   std::shared_ptr<std::string>,这样的话内存会在.dll中创建和释放。

还有一个方法是使用 char *,并指明它预开辟空间的大小。如果我们发现传回的内存长度和我们预开辟的大小不一样,那么我们可以返回一个错误。

重要:

我把MSVC Runtime library设定为Multi-threaded Debug DLL (/MDd),问题就解决了。

另外一个讲到这个问题的博客:http://blog.csdn.net/giantpoplar/article/details/47295877



  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 这个错误信息表示在表达式中断言失败:'errors == mdb_success || errors == mdb_notfound'。这意味着程序检测到了一个不符合预期的错误,并无法继续执行。具体的错误原因需要进一步调查。 ### 回答2: 这个错误信息可能出现在使用 mdb (MonDgoDB) 数据库时,执行相关操作时遇到了错误。 assertion failed on expression: 'errors == mdb_success || errors == mdb_notfound' 的意思是,在执行 具体的操作(具体操作因情况而异)过程中,系统预期的操作结果是 mdb_success 或者是 mdb_notfound,但实际上得到的操作结果与预期结果不符,导致了程序报错。 可能的原因包括: 1. 数据库连接出现问题。例如,连接时的参数设置不正确,或者连接过程中网络发生异常等。 2. 操作的数据不存在。程序在尝试访问/修改数据时,发现数据并不存在。 3. 操作的数据未能正确处理。例如,在对数据进行修改时,程序出现某些未处理的错误,导致操作结果错误。 在出现这个错误信息时,需要仔细的检查相关的操作代码,并根据具体情况调试程序。可以通过查看日志、尝试重新连接数据库等方式找到问题所在,并根据实际情况进行修复。需要注意,在修复程序时需要避免对数据的丢失或破坏。 ### 回答3: 这是一个关于Mongodb数据库操作的问题。通常情况下,当我们在操作Mongodb数据库时,会使用一些操作指令来进行增、删、改、查等操作。如果在执行这些操作时,出现了错误,系统会返回一个错误码,用来告诉我们这个操作是否成功,以及出错的原因。 这个问题中的assertion failed on expression: 'errors == mdb_success || errors == mdb_notfound'告诉我们的是,在执行Mongodb的操作时,出现了assertion failed的错误,并且错误的信息是errors == mdb_success || errors == mdb_notfound。那么,这个错误的具体含义是什么呢? 在Mongodb的驱动库中,有两个常量mdb_success和mdb_notfound,分别表示查询成功和查询结果不存在。错误信息中的errors == mdb_success || errors == mdb_notfound就是在判断数据库操作是否成功的时候用到的,如果errors等于mdb_success或者等于mdb_notfound,说明操作成功,否则就是操作失败了。 在这个错误信息中,出现assertion failed,表示出现了断言错误,也就是说,在系统判断操作是否成功的时候,出了问题。这可能是由于程序逻辑出现了问题,导致判断错误,或者是Mongodb服务的异常状态导致的。 为了解决这个问题,我们需要仔细检查程序逻辑,并在数据库服务状态正常时再次进行操作,以确保操作成功。如果问题依然无法解决,建议联系Mongodb官方技术支持人员协助解决。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值