【问题标题】:std::locale segfault on OS X, cannot reproduce on any other platformOS X 上的 std::locale 段错误,无法在任何其他平台上重现
【发布时间】:2014-08-05 03:54:42
【问题描述】:

我为我的上一个问题generate range for which std::isalpha evaluates to true 建议了以下代码。它显示当前语言环境中的所有chars,isalpha 的计算结果为true,因此对于英语语言环境,它显示AB...Zab...z。但是,当我尝试访问table 时,我在if(table[i] & ctype::alpha) 线上收到了Segmentation fault: 11。我在 OS X Mavericks 10.9.4 上使用 g++4.9 和 clang++(Apple LLVM 版本 5.1 (clang-503.0.40) )编译了它。在所有其他平台(Linux/Solaris)上它都可以工作,没有分段错误。

谁能指出 OS X 上的 C++ 的 libc++/libstdc++ 是否有问题,或者至少问题是否可重现?

#include <iostream>
#include <locale>

int main() {
    typedef std::ctype<char> ctype;
    std::locale locale;
    const ctype& facet = std::use_facet<ctype>(locale);
    const ctype::mask* table = facet.table();

    // You might skip this and work with the table, only.
    std::string result;
    for(unsigned i = 0; i < facet.table_size; ++i) {
        if(table[i] & ctype::alpha)
            result += char(i);
    }
    std::cout << result << '\n';
    return 0;
}

PS:几个小时后,我发现(按照霍华德的建议)clang++ 在默认情况下使用 libstdc++(为什么我还没有发现),这似乎在语言环境支持方面被破坏了。使用 libc++ 编译时,程序按预期运行。

【问题讨论】:

  • facet.table(); 在这种情况下将返回classic_table(),因为您使用的是默认的 C 语言环境,它是 OSX 的空指针。遗憾的是,OSX 上的 C++ 语言环境支持非常少。
  • 这里的教训是:始终检查函数返回值是否有效。
  • @user657267,谢谢!我想知道为什么我还没有检查 nullptr... 有什么特殊原因导致 OS X 不正确支持语言环境吗?
  • @JoachimPileborg 课程学得不够好:)
  • @vsoftco GCC on OSX 只能使用generic 语言环境模型编译,因为不支持gnu 模型。我猜这同样适用于 Clang。 generic 模型仅对语言环境提供准系统支持(几乎所有你得到的都是默认的 C 语言环境)。关于检查指针,这是一个诚实的错误,根据标准,返回值应该是一个长度为 table_size 的数组,并且实现似乎不允许任何异常来提供自己的行为。

标签: c++ c++11 segmentation-fault locale


【解决方案1】:

还不如把我的cmets变成答案:

由于 libstdc++ 不支持 OSX 上的“通用”语言环境模型,因此几乎不支持 C++ 语言环境。您的段错误是由 facet.table(); 返回一个空指针引起的(标准实际上不允许这样做)。

遗憾的是,目前唯一的解决方案是完全远离 OSX 上的语言环境,或者改用 libc++,正如@HowardHinnant 指出的那样工作正常。

【讨论】:

    【解决方案2】:

    我在 OS X Mavericks 10.9.4 上使用 clang++(Apple LLVM 版本 5.1 (clang-503.0.40)),您的程序对我来说运行良好。我补充说:

    assert(table != nullptr);
    assert(table == facet.classic_table());
    

    两个断言都通过了。编译:

    clang++ test.cpp
    

    【讨论】:

    • 很奇怪,我也在使用完全相同的clang++,相同的 OS X 版本,并在我的笔记本电脑和 iMac 上进行了测试,并且断言失败 (nullptr)两者。
    • 你的 clang++ 和 XCode 中的一样吗(和我的一样)?
    • 是的。在这个操作系统/工具上,默认是使用 libc++,而不是 libstdc++。我实现了 libc++ 的这一部分。我唯一的解释是你不知何故拿起了 gcc libstdc++。
    • 是的!你是对的,clang++ 正在接收libstdc++,我现在用-stdlib=libc++ 编译它,它按预期工作。另一个g ++问题......为什么clang ++使用libstdc ++我还没有弄清楚,这可能是我使用macports安装g ++后的路径问题。
    • 又一个在 OSX 上切换到 libc++ 的理由。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-15
    • 2014-07-18
    • 1970-01-01
    • 1970-01-01
    • 2011-11-13
    相关资源
    最近更新 更多