【问题标题】:Boost streambuf to const char* with buffer_cast vs std::string vs ostringstream使用 buffer_cast vs std::string vs ostringstream 将 streambuf 提升为 const char*
【发布时间】:2014-07-09 07:53:06
【问题描述】:

我有一个使用 boost::read_until 和 boost::streambuf 的客户端/服务器应用程序。我正在从套接字读取 XML 消息,并想用 tinyXML2 解析它,如下所示:

XMLDocument doc;
doc.parse(strPtr); // strPtr is const char* 

我需要以某种方式从 streambuf 中提取 const char *strPtr。到目前为止,我在堆栈交换中找到了三种方法:

// method 1, string constructor
const char * streambufToPtr(boost::asio::streambuf &message) {
    boost::asio::streambuf::const_buffers_type bufs = message.data();
    std::string astr(boost::asio::buffers_begin(bufs), boost::asio::buffers_begin(bufs) + message.size());
    return astr.c_str();
}

// method 2, stringstream
const char * streambufToPtr(boost::asio::streambuf &message) {
    std::ostringstream ss;
    ss << &message;
    std::string astr = ss.str();
    return astr.c_str();
}

// method 3, buffer_cast
const char * streambufToPtr(boost::asio::streambuf &message) {
    const char* bufPtr=boost::asio::buffer_cast<const char*>(message.data());
    return bufPtr;
}

这三种方法都适用于我的代码(到目前为止)。方法 1 和 2 可能至少复制数据一次(或更多),而方法 3 执行其他操作。

每种方法都发生了什么? 相比之下,它们的速度有多快? 就缓冲区溢出、线程或其他我以后可能在网络客户端/服务器应用程序中遇到的陷阱而言,这些是否不安全?

【问题讨论】:

    标签: c++ xml boost tinyxml streambuf


    【解决方案1】:

    每种方法的作用是什么?

    第一个方法将字节复制到std::string 并返回一个指向底层char 数组的指针。这会导致未定义的行为,因为字符串在函数返回时被破坏,不要使用它。

    第二种方法首先将字节复制到ostringstream,然后复制到字符串(ss.str();),然后再复制到另一个字符串(std::string astr =,尽管编译器可能会忽略最后一个副本)。它还返回一个指针,该指针指向函数返回时将不再存在的东西,不要使用它。

    您的最终函数只是返回一个指向缓冲区底层字节的指针,并且是三个中唯一一个具有明确定义行为的函数(假设您的 streambuf 比您传递给 tinyXML2 的 char 指针寿命更长,并且在此期间没有修改)。

    相比之下,它们的速度有多快?这些中的任何一个在以下方面是否不安全? 缓冲区溢出、线程或其他我以后可能会遇到的陷阱 网络客户端/服务器应用程序?

    这些没有实际意义,因为其他两个功能没用。

    【讨论】:

    • 谢谢,很有帮助!
    • 只是为了完全弄清楚这一点:如果我不将方法 1 和 2 包装到上面的函数中,而是在 asr 超出范围之前调用 doc.parse(astr.c_str()),字符串尚未销毁。然后这些方法就可以使用了,对吧(除了不需要的复制)?
    • @frankhond 是的,这将按预期工作,只要字符串在范围内且未修改,c_str() 返回的指针就有效。您还可以使用istreambuf_iterator 创建字符串。
    猜你喜欢
    • 2013-11-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-28
    • 2011-01-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多