2010-12-21 93 views
3

我偶尔会从boost :: lower获得奇怪的行为,当调用std :: wstring时。特别是,我已经看到了以下断言在发布版本失败(但不调试版本):什么导致boost :: lower会失败is_singular断言?

Assertion failed: !is_singular(), file C:\boost_1_40_0\boost/range/iterator_range.hpp, line 281 

我还看到了什么叫出现的boost :: to_lower在上下文之后是内存错误如:

void test(const wchar_t* word) { 
    std::wstring buf(word); 
    boost::to_lower(buf); 
    ... 
} 

更换boost::tolower(wstr)std::transform(wstr.begin(), wstr.end(), wstr.begin(), towlower)出现来解决这个问题的呼叫;但我想知道发生了什么问题。

我最好的猜测是,也许这个问题与更改Unicode字符的情况有关 - 也许编码大小的downcased字符是不同于源字符的编码大小?

有没有人有任何想法可能会发生在这里?如果我知道“is_singular()”在提升的背景下意味着什么,可能会有所帮助,但是在执行一些谷歌搜索之后,我无法找到任何文档。

相关软件版本:Boost 1.40.0; MS Visual Studio 2008.

回答

3

经过进一步调试,我找出了发生了什么事。

我的麻烦原因是解决方案中的一个项目没有定义NDEBUG(尽管处于发布模式),而所有其他模块都是。 Boost在其数据结构中分配一些额外的字段,用于存储调试信息(例如数据结构是否已初始化)。如果模块A调试关闭,那么它将创建不包含这些字段的数据结构。然后,当开启了调试功能的模块B掌握了该数据结构之后,它将尝试检查这些字段(未分配),导致随机存储器错误。

定义NDEBUG在全部项目中的解决方案解决了这个问题。

3

如果默认构造函数构造了迭代器范围(存储单数迭代器,即不表示范围),则迭代器范围应该是单数。由于很难相信该提升的功能可以创建一个单独的范围,它表明这个问题也可能在其他地方(由于某些未定义的行为,例如使用未初始化的变量,这些变量可能被初始化为调试中的某个已知值编译)。

了解更多关于Heisenbugs

相关问题