【问题标题】:What is causing boost::lower to fail an is_singular assertion?是什么导致 boost::lower 使 is_singular 断言失败?
【发布时间】:2011-05-29 02:18:01
【问题描述】:

当在 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。

【问题讨论】:

    标签: c++ boost


    【解决方案1】:

    只有使用默认构造函数构造的迭代器范围才应该是单数的(存储单数迭代器,即不代表范围)。由于很难相信 boost 的 to_lower 函数设法创建了一个奇异范围,这表明问题也可能出在其他地方(某些未定义行为的结果,例如使用可能被初始化为某个已知值的未初始​​化变量在调试版本中)。

    阅读更多关于Heisenbugs

    【讨论】:

      【解决方案2】:

      经过进一步调试,我弄清楚了发生了什么。

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

      在解决方案的所有个项目中定义 NDEBUG 解决了问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-07-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-08-17
        • 2021-05-09
        相关资源
        最近更新 更多