当我在std :: wstring上调用时,我偶尔会从boost :: lower获得奇怪的行为。特别是,我在发布版本中看到以下断言失败(但在调试版本中不是):
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字符的情况有关 - 也许下层字符的编码大小与源字符的编码大小不同?
有没有人有任何想法可能会发生在这里?如果我知道“is_singular()”在boost的上下文中意味着什么可能会有所帮助,但在做了一些谷歌搜索之后我无法找到任何文档。
相关软件版本:Boost 1.40.0; MS Visual Studio 2008。
答案 0 :(得分:3)
如果迭代器范围是使用默认构造函数构造的,则它应该只是单数(存储奇异迭代器,即不表示范围)。由于很难相信boost to_lower
函数设法创建一个奇异范围,它表明问题也可能在其他地方(某些未定义行为的结果,例如使用未初始化的变量,可能会初始化为某些调试版本中的已知值。
详细了解Heisenbugs。
答案 1 :(得分:3)
经过进一步的调试,我弄明白发生了什么。
我遇到麻烦的原因是解决方案中的一个项目没有定义NDEBUG(尽管处于发布模式),而所有其他模块都是。 Boost在其数据结构中分配一些额外的字段,用于存储调试信息(例如数据结构是否已初始化)。如果模块A关闭了调试,那么它将创建不包含这些字段的数据结构。然后,当启用了调试的模块B接触到该数据结构时,它将尝试检查那些字段(未分配),从而导致随机存储器错误。
在解决方案的所有项目中定义NDEBUG解决了问题。