我有一个使用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则执行其他操作。
每种方法都有什么变化? 他们相比有多快? 在缓冲区溢出,线程或其他陷阱方面,我可能会在以后使用网络客户端/服务器应用程序遇到这些问题吗?
答案 0 :(得分:3)
每种方法的内容是什么?
第一种方法将字节复制到std::string
并返回指向底层char
数组的指针。这导致未定义的行为,因为函数返回时字符串被销毁,请不要使用它。
第二种方法首先将字节复制到ostringstream
,然后复制到字符串(ss.str();
),然后复制到另一个字符串(std::string astr =
,尽管编译器可能会忽略最后一个副本)。它还返回一个指向函数返回时不再存在的东西的指针,不要使用它。
你的最后一个函数只是返回一个指向缓冲区底层字节的指针,并且是三个中具有明确定义行为的唯一一个(假设你的streambuf
超过了char
指针你传递给tinyXML2,并且在此期间不会被修改。
他们相比有多快?这些中的任何一个都是不可取的 缓冲区溢出,线程或其他陷阱我可能会在以后遇到 网络客户端/服务器应用程序?
这些都没有实际意义,因为其他两个功能都是无用的。