【问题标题】:g++ regex crash on (possibly unsyntactic) expressiong ++正则表达式在(可能是非语法的)表达式上崩溃
【发布时间】:2014-01-24 04:11:32
【问题描述】:

我认为下面的程序要么抱怨它不能编译正则表达式,要么将其视为合法并编译它(我没有标准,所以我不能确定表达式是否严格合法的;当然合理的解释是可能的)。无论如何,g++ (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1 发生的事情是,在运行时,它会严重崩溃

*** Error in `./a.out': free(): invalid next size (fast): 0x08b51248 ***

在图书馆的内脏中。

问题是:

a) 这是错误,对吧?我假设(也许是错误的)标准没有说 std::regex 如果它不喜欢语法会崩溃。 (msvc 吃得很好,fwiw)

b) 如果它是一个错误,是否有一些简单的方法可以查看它是否已被报告(我第一次在 gnu-land 错误系统上闲逛是令人生畏的)?

#include <iostream>
#include <regex>

int main(void)
    {
    const char* Pattern = "^(%%)|";
    std::regex Machine;

    try {
        Machine = Pattern;
        }
    catch(std::regex_error e)
        {
        std::cerr << "regex could not compile pattern: "
          << Pattern << "\n"
          << e.what() << std::endl;
        throw;
        }

    return 0;
    }

【问题讨论】:

  • 我会说你在正则表达式解析器中有一个错误,因为它应该做的是匹配任何东西。管道字符指示正则表达式解析器匹配其任一侧的表达式。因为在你的情况下,右手边是空的,它应该匹配任何东西。我猜你想匹配一个管道字符,因此应该逃脱它并且它应该可以工作。
  • 顺便说一句,这个正则表达式只是一个测试,还是你想做什么?
  • &lt;regex&gt; 在 gcc-4.8.1 的 libstdc++ 中不起作用。如果您可以使用 LLVM 的 libc++,请使用它,your program works。否则 - boost.regex
  • @ClasG 在过去(在 Ken Thompson 的精彩算法发布后不久),带有空参数的 | 用于匹配 epsilon(零字符),有效地提供了 ? 运算符无需保留另一个特殊字符。这个错误来自以编程方式从模式/toktypes 表生成基于正则表达式的词法分析器的代码。我将其修改为对 another 正则表达式错误的二进制搜索,结果错误地以 | 结尾。
  • @Cubbi 谢谢!我正要反驳说 4.8.1 声称支持正则表达式,但我发现我被 0.0.1 版本所取代!好的,现在我只需要弄清楚如何获得一个运行 4.8.2 的系统。这个项目的部分目的是探索两个主要编译器对黄金时间 C++ 11 的支持有多好(就正则表达式而言,比 Bjarne 想象的要少一些),所以我对替代库不感兴趣,但可以用 vanilla C++ 11 完成。

标签: c++ regex c++11 crash g++4.8


【解决方案1】:

我会把它放在评论中,但我不能,所以......

我不知道你是否已经知道,但它似乎是管道 |最后导致你的问题的字符。似乎 | 的字符表示当正则表达式尝试调用 free() 时,g++ 给出的最后一个字符(因为 "^(%%)|a" 对我来说很好用);

标准(或至少我正在阅读的在线草案)声称:

28.8
Class template basic_regex
[re.regex]

1 For a char-like type charT, specializations of class template basic_regex represent regular expressions
constructed from character sequences of charT characters. In the rest of 28.8, charT denotes a given char-
like type. Storage for a regular expression is allocated and freed as necessary by the member functions of
class basic_regex.

2 Objects of type specialization of basic_regex are responsible for converting the sequence of charT objects
to an internal representation. It is not specified what form this representation takes, nor how it is accessed by
algorithms that operate on regular expressions.
[ Note: Implementations will typically declare some function
templates as friends of basic_regex to achieve this — end note ]

以后,

basic_regex& operator=(const charT* ptr);

3 Requires: ptr shall not be a null pointer.

4 Effects: returns assign(ptr).

所以除非 g++ 认为 const char* Pattern ="|";是一个空指针(我想不是...), 我猜这是一个错误?

编辑:顺便说一下,连续的|| (即使不是在最后)似乎也对我造成了分段错误。

【讨论】:

  • 这可能是我能得到的最好的答案;它至少增强了我的信心,即正则表达式语法错误未被归类为“未定义的行为”。
  • 所以我也不能评论其他人的 cmets,但关于你对@Cubbi 的评论,我昨天才在集群上安装 gcc-4.8.2 到我的 $HOME/gcc没有 root 访问权限的目录,所以如果您仍然想这样做,也许我可以提供帮助?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多