代码之家  ›  专栏  ›  技术社区  ›  frankhond

使用buffer_cast vs std::string vs ostringstream将streambuf提升为常量char*

  •  3
  • frankhond  · 技术社区  · 10 年前

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

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

    我需要从streambuf中提取constchar*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执行其他操作。

    每种方法都发生了什么? 相比之下,它们的速度有多快? 在缓冲区溢出、线程或其他陷阱方面,这些都是不安全的吗?

    1 回复  |  直到 10 年前
        1
  •  3
  •   user657267    10 年前

    每种方法都发生了什么?

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

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

    最后一个函数只是返回一个指向缓冲区底层字节的指针,它是三个函数中唯一一个具有定义良好行为的函数(假设 streambuf 烧焦 您传递给tinyXML2的指针,同时不会被修改)。

    相比之下,它们的速度有多快?就以下方面而言,这些产品中有哪些不受欢迎 缓冲区溢出、线程或其他陷阱 网络客户端/服务器应用程序?

    这些都是没有意义的,因为其他两个函数都是无用的。