gsl::span, возвращаемый функцией, имеет неверные байты

У меня есть функция, анализирующая составное сообщение 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)?


person Marco Stramezzi    schedule 10.10.2017    source источник
comment
gsl::span<uint8_t> – это невладелец представления.   -  person Jarod42    schedule 10.10.2017


Ответы (1)


auto body = msg.pop();

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

body — это локальная переменная внутри функции. span относится к байтам, принадлежащим body, но body уничтожается при выходе из функции, поэтому ваш span в parsed.body больше не указывает на действительные байты, когда вы пытаетесь использовать его вне parseForwarderToClient.

person xaxxon    schedule 10.10.2017
comment
Хорошо, спасибо, я понял свою ошибку. Но есть ли способ заставить мой код работать должным образом? - person Marco Stramezzi; 10.10.2017
comment
сохраните его, например, внутри std::vector<uint8_t>. - person Jarod42; 10.10.2017