Mingw32-w64 GCC 4.9.2 正则表达式漏洞,还是我不懂C++?

3
#include <iostream>
#include <vector>
#include <regex>

using namespace std;

int main()
{
    char rs[] = R"((\s+)|([\r\n][\r\n]?))"; /* split on whitespace or newline */
    regex r(rs); // this regex declared like a local variable
    string s("foo  bar \t baz\nqux quux corge");

/* Part 1 */

    sregex_token_iterator
            first {begin(s), end(s), r, -1},
            last;
    vector<string> tokens1 {first, last};
    for(auto i : tokens1) {
        cout << i << ", ";
    }

/* Part 2 */

    cout << endl << endl << "inline:";
    //string regexstring(rs); // <<< uncomment for different behavior

    /* here, the regex is created inline */
    sregex_token_iterator
            first2 {begin(s), end(s), regex(rs), -1},
            last2;

    vector<string> tokens2 {first2, last2};

    for(auto i : tokens2) {
        cout << i << ", ";
    }
}

这件事让我烦了很长时间。这个程序在我的电脑上崩溃了,它在从tokens2打印令牌时被卡死在某个循环中,直到发生段错误。如果你取消注释所示的行,程序就可以运行。然而,只有tokens1包含了正确分割的令牌,我看不出区别所在。

这是一个简化的最小实例,在装有WinXP SP3、Code::Blocks和新下载的来自Sourceforge(今天)的Mingw64 GCC 4.9.2 for win32的机器上重现了这种行为。我用TDM-GCC-W32构建GCC 4.9.2也得到了同样的结果。

显然这必须是2个错误吧?或者我真的不理解C ++?

1个回答

5
regex_token_iterator 不适用于使用临时 regex 对象的调用,正如您在第二部分中所做的一样,因为它不存储 regex 实例的副本。由于表达式结束时摧毁了regex实例,导致调用结果是一个已经失效的迭代器,Part 2 导致未定义的行为。
通过添加 deleted rvalue 重载函数,C++14解决了这个问题,这将防止第二个示例的编译。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接