2

我有一个使用 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 执行其他操作。

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

4

1 回答 1

3

每种方法发生了什么?

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

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

您的最终函数只是返回一个指向缓冲区底层字节的指针,并且是三个中唯一一个具有明确定义的行为(假设您的指针超过了传递给 tinyXML2streambuf的指针,并且同时没有修改) char.

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

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

于 2014-07-09T08:26:41.510 回答