【问题标题】:Expression: string iterator not dereferencable while using boost regex表达式:字符串迭代器在使用 boost 正则表达式时不可取消引用
【发布时间】:2012-07-25 14:02:27
【问题描述】:

我想从一个页面中恢复所有链接,在执行这段代码时我得到:

Microsoft Visual C++ 调试库

调试断言失败!

程序:C:\Users\Gandalf\Desktop\proxy\Debug\Proxy.exe 文件: C:\Program Files\Microsoft Visual Studio 10.0\VC\include\xstring 行: 78

表达式:字符串迭代器不可解引用

有关您的程序如何导致断言失败的信息, 请参阅有关断言的 Visual C++ 文档。

(按重试调试应用程序)

中止重试忽略

void Deltacore::Client::get_links() {
boost::smatch matches;
boost::match_flag_type flags = boost::match_default;
boost::regex URL_REGEX("^<a[^>]*(http://[^\"]*)[^>]*>([ 0-9a-zA-Z]+)</a>$");

if(!response.empty()) {

    std::string::const_iterator alfa = this->response.begin();
    std::string::const_iterator omega   = this->response.end();

    while (boost::regex_search(alfa, omega, matches, URL_REGEX))
    {
        std::cout << matches[0];
        //if(std::find(this->Links.begin(), this->Links.end(), matches[0]) != this->Links.end()) {
            this->Links.push_back(matches[0]);
        //}
        alfa = matches[0].second;
    }
}
}

有什么想法吗?

添加了更多代码:

        Deltacore::Client client;
    client.get_url(target);
    client.get_links();

            boost::property_tree::ptree props;
            for(size_t i = 0; i < client.Links.size(); i++)
                props.push_back(std::make_pair(boost::lexical_cast<std::string>(i), client.Links.at(i)));

            std::stringstream ss;
            boost::property_tree::write_json(ss, props, false);

            boost::asio::async_write(socket_,
                boost::asio::buffer(ss.str(), ss.str().length()),
                boost::bind(&session::handle_write, this,
                boost::asio::placeholders::error));

提前致谢

【问题讨论】:

  • 尝试使用 std::string::iterator 而不是 const_iterator。
  • @Wug 它在 C++ 基本包含中,我很确定错误在我的代码中。
  • @Mahesh boost::regex_search 出于某种原因迫使我使用 std::string::const_iterator
  • 也许它想要 end() - 1 什么的。这是一个断言吧? (它说是。)在获得迭代器之前,字符串的值是多少?
  • this->response 是页面的完整 HTML 输出(我使用 cURL 获取)。

标签: c++ regex visual-c++ boost boost-regex


【解决方案1】:

问题出在这一行:

boost::asio::buffer(ss.str(), ss.str().length())

str() 返回一个 temporary std::string 对象,因此您实际上是在创建缓冲区后立即使其无效 - 正如我评论的那样,香草 UB。 ;-]

令牌documentation citation

缓冲区因对给定字符串对象调用的任何非常量操作而失效。

当然,销毁字符串是非常量的操作。

【讨论】:

  • 这实际上修复了它。谢谢你。现在是凌晨 2 点,我正在编写错误的代码:/
【解决方案2】:

跳过关于使用正则表达式解析 HTML 的讲座(以及你真的不应该如何......),你的正则表达式看起来不像你想要的那样工作。这是你的:

"^<a[^>]*(http://[^\"]*)[^>]*>([ 0-9a-zA-Z]+)</a>$"

第一个字符类将是贪婪的,会吃掉你的 http 和后续部分。你想加个问号让它不贪心。

"^<a[^>]*?(http://[^\"]*)[^>]*>([ 0-9a-zA-Z]+)</a>$"

这可能与异常有关,也可能无关。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-08
    • 2022-10-01
    相关资源
    最近更新 更多