gsl::span returned by function has wrong bytes

620 Views Asked by At

I have a function parsing a ZeroMQ multipart message and filling a struct containing a 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;
}

The function calling this method does the following:

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;

The problem is that bytes printed with msg.str() and inside parseForwarderToClient are the same, while the ones printed in calling funciton are different (and then my code crash).

What am I doing wrong in this code (I am still a newbie in C++11/14 and gsl features)?

1

There are 1 best solutions below

2
On BEST ANSWER
auto body = msg.pop();

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

body is a local variable inside the function. The span refers to bytes owned by body, but body is destroyed when the function exits, therefor your span in parsed.body is no longer pointing to valid bytes when you try to use it outside of parseForwarderToClient.