函数返回的 gsl::span 具有错误的字节

gsl::span returned by function has wrong bytes

本文关键字:有错误 字节 span gsl 函数 返回      更新时间:2023-10-16

我有一个函数来解析 ZeroMQ 多部分消息并填充包含gsl::span<uint8_t>的结构:

struct ProtocolMessage{
    ProtocolMessage() {}
    ProtocolMessage(std::initializer_list<std::string> headers): 
        headers{headers} {}
    ProtocolMessage(std::initializer_list<std::string> headers, gsl::span<uint8_t> body): 
        headers{headers}, body{body} {}
    ~ProtocolMessage() = default;
    std::vector<std::string> headers;
    gsl::span<uint8_t> body;
};
ProtocolMessage ProtocolAsts1::parseForwarderToClient(zmq::multipart_t&& msg) const {
    ProtocolMessage parsed;
    parsed.headers.push_back(msg.popstr());
    auto body = msg.pop();
    parsed.body = gsl::span<uint8_t>{body.data<uint8_t>(), body.size()};
    std::cout << "parseForwarderToClient" << std::endl;
        for(size_t i = 0; i < parsed.body.size(); ++i)
    std::cout << std::hex << std::setw(2) << std::setfill('0') << static_cast<short>(parsed.body.data()[i]);
    std::cout << std::dec << std::endl;
    return parsed;
}

调用此方法的函数执行以下操作:

zmq::multipart_t msg{socketForwarder};
std::cout << msg.str();
auto parsed = parser->parseForwarderToClient(std::move(msg));
std::cout << "doLoop" << std::endl;
for(size_t i = 0; i < parsed.body.size(); ++i)
    std::cout << std::hex << std::setw(2) << std::setfill('0') << static_cast<short>(parsed.body.data()[i]);
std::cout << std::dec << std::endl;

问题是用 msg.str()parseForwarderToClient 内部打印的字节是相同的,而在调用函数中打印的字节是不同的(然后我的代码崩溃)。

我在这段代码中做错了什么(我仍然是 C++11/14 和 gsl 功能的新手)?

auto body = msg.pop();
parsed.body = gsl::span<uint8_t>{body.data<uint8_t>(), body.size()};

body是函数内的局部变量。 span是指body拥有的字节,但是当函数退出时body被销毁,因此当您尝试在parseForwarderToClient之外使用它时,您在parsed.body中的span不再指向有效字节。