Asio :: buffer_cast странный вывод

Я изучаю boost :: asio и столкнулся с проблемой. По сути, asio :: buffer_cast () на моей машине работает странно. Любая помощь будет принята с благодарностью.

У меня есть следующий пример кода:

#include <iostream>
#include <vector>
#include <sstream>
#include <iomanip>
#include <boost/asio.hpp>
int main ()
{  
std::ostringstream type_stream;
type_stream << std::setw(4) << 100;
std::cout<<"type_stream:"<<type_stream.str()<<std::endl;

std::ostringstream head_stream;
head_stream << std::setw(10) << 92;
std::cout<<"head_stream:"<<head_stream.str()<<std::endl;

std::vector<boost::asio::const_buffer> buffers;
buffers.push_back(boost::asio::buffer(type_stream.str()));
buffers.push_back(boost::asio::buffer(head_stream.str()));

auto test = buffers[0];
const unsigned char* p1 = boost::asio::buffer_cast<const unsigned char*>(test);
std::cout<<"type_stream again:"<<std::string(reinterpret_cast<const char*>(p1))<<std::endl;

auto test2 = buffers[1];
const unsigned char* p2 = boost::asio::buffer_cast<const unsigned char*>(test2);
std::cout<<"head_stream again:"<<std::string(reinterpret_cast<const char*>(p2))<<std::endl;

return 0;
}

Если вы запустите этот код здесь: https://wandbox.org/permlink/4VkxJ4TFgjHzrath, он будет работать нормально. На выходе

type_stream: 100
head_stream:        92
type_stream again: 100
head_stream again:        92

Но когда я поместил код в функцию и запустил на моей машине, я получил вывод как

type_stream: 100
head_stream:        92
type_stream again:        92
head_stream again:        92

Я что-то не так делаю в коде? Кажется, на моей машине второй буфер перекрыл первый. У меня есть gcc (Ubuntu 7.2.0-8ubuntu3.2) 7.2.0 и новейший boost :: asio.

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
2
0
478
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Да, есть Неопределенное поведение.

Проблема в том, что

 buffers.push_back(boost::asio::buffer(type_stream.str()));

type_stream.str() возвращает временный std::string, и поэтому буфер недействителен после нажатия.

Исправить:

Live On Coliru

#include <boost/asio.hpp>
#include <boost/lexical_cast.hpp>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <vector>

std::string format_buf(int v, int width) {
    std::ostringstream oss;
    oss << std::setw(width) << v;
    return oss.str();
}

int main() {
    std::string type_str = format_buf(100, 4);
    std::string head_str = format_buf(92, 10);

    std::cout << "type_stream first: " << std::quoted(type_str) << std::endl;
    std::cout << "head_stream first: " << std::quoted(head_str) << std::endl;

    std::vector<boost::asio::const_buffer> buffers;
    buffers.push_back(boost::asio::buffer(type_str));
    buffers.push_back(boost::asio::buffer(head_str));

    auto test = buffers[0];
    const unsigned char *p1 = boost::asio::buffer_cast<const unsigned char *>(test);
    std::cout << "type_stream again:" << std::quoted(reinterpret_cast<const char *>(p1)) << std::endl;

    auto test2 = buffers[1];
    const unsigned char *p2 = boost::asio::buffer_cast<const unsigned char *>(test2);
    std::cout << "head_stream again:" << std::quoted(reinterpret_cast<const char *>(p2)) << std::endl;
}

Отпечатки

type_stream first: " 100"
head_stream first: "        92"
type_stream again:" 100"
head_stream again:"        92"

БОНУС

Поскольку вы фактически пытаетесь использовать форматирование с фиксированной шириной (?), Почему бы не сделать его более простым и надежным:

Live On Coliru

char type[4] = {};
char head[10] = {};

bio::stream<bio::array_sink> tstream(type);
tstream << 100;

bio::stream<bio::array_sink> hstream(head);
hstream << 92;

Это более надежно, потому что с вашим кодом поля могут быть слишком широкими (например, с типом, содержащим 12345)

благодарю вас! Насколько я глуп :) Я не очень разбираюсь в array_sink, кажется, что тип и голова соединяются вместе.

J.Yang 01.11.2018 15:52

Будет, если вы используете тот же буфер. Я сделаю разницу между tstream и hstream более очевидной в моем фрагменте "БОНУС"

sehe 01.11.2018 15:58

С помощью @sehe работает следующий код. Но у меня появились новые заботы. Можно ли создать char type[4] = {}; char head[10] = {}; char type2[2] = {}; внутри функции prepareBuffers()? Поскольку буфер был создан buffers.push_back(boost::asio::buffer(type));, я подозреваю, что тип будет уничтожен при выходе из функции prepareBuffers(). Но в main() программа все еще может получить доступ к содержимому буфера. Есть ли копия бывает?

#include <boost/asio.hpp>
#include <boost/iostreams/device/array.hpp>
#include <boost/iostreams/stream.hpp>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <vector>

namespace bio = boost::iostreams;

void prepareBuffers(std::vector<boost::asio::const_buffer> & buffers){
char type[4] = {};
char head[10] = {};

bio::stream<bio::array_sink> tstream(type);
bio::stream<bio::array_sink> hstream(head);

tstream << 555555;
hstream << 923;

std::cout << "type_stream first: " << std::quoted(type) << std::endl;
std::cout << "head_stream first: " << std::quoted(head) << std::endl;

buffers.push_back(boost::asio::buffer(type));
buffers.push_back(boost::asio::buffer(head)); 

auto test = buffers[0];
const unsigned char* p1 = boost::asio::buffer_cast<const unsigned char*>(test);
std::cout<<"in function type_stream again:"<<std::string(reinterpret_cast<const char*>(p1))<<std::endl;

test = buffers[1];
const unsigned char* p2 = boost::asio::buffer_cast<const unsigned char*>(test);
std::cout<<"in function head_stream again:"<<std::string(reinterpret_cast<const char*>(p2))<<std::endl;
}

int main() {
std::vector<boost::asio::const_buffer> buffers2;
prepareBuffers(buffers2);

auto test21 = buffers2[0];
const unsigned char* p1 = boost::asio::buffer_cast<const unsigned char*>(test21);
std::cout<<"type_stream again:"<<std::string(reinterpret_cast<const char*>(p1))<<std::endl;

auto test22 = buffers2[1];
const unsigned char* p2 = boost::asio::buffer_cast<const unsigned char*>(test22);
std::cout<<"type_stream again:"<<std::string(reinterpret_cast<const char*>(p2))<<std::endl;

return 0;
}

Другие вопросы по теме