Принудительно увеличить :: asio :: буфер для копирования по значению - PullRequest
9 голосов
/ 02 мая 2011

Я использую boost :: asio :: buffer для отправки сообщения, используя

void Send(const std::string& messageData)
{
    socket.async_write(boost::asio::buffer(messageData), ...);
}

И сталкиваюсь с ошибкой во время выполнения «string iterator not dereferencable» где-то в потоке io_service.Когда я создаю переменную объектов для хранения данных сообщения для буфера:

void Send(const std::string& messageData)
{
    this->tempStorage = messageData;
    socket.async_write(boost::asio::buffer(this->tempStorage), ...);
}

, ошибка никогда не возникает.std :: string (на который ссылается messageData) освобождается почти сразу после вызова Send () - сохраняет ли boost :: asio :: buffer только ссылку на объект?Если да, то как я могу заставить его хранить данные по значению?

Ответы [ 2 ]

15 голосов
/ 07 мая 2011

Ответ из списков рассылки boost-пользователей:

Если бы это было так, это было бы совершенно бесполезно, так как у вас нет доступа к любой из буферов в вашем обработчике завершения.

Способ использования buffer () - передать ссылки на хранилище, которое вы гарантировать срок службы каким-либо другим способом.

Вы можете сохранить его во внешнем объекте или сохранить в `this ', как вы сделали, или связав его в функцию обработчика завершения сам объект.

void onComplete(shared_ptr<std::string> s, error_code const&, size_t)
{
    // do stuff
}

void send(std::string const& messageData)
{
    shared_ptr<std::string> s = make_shared<std::string>(messageData);
    async_send(socket, boost::asio::buffer(*s),
    boost::bind(&T::onSend, this, s, _1, _2));
}

Это гарантирует, что время жизни данных буфера будет по крайней мере таким же обработчик завершения существует.

1 голос
/ 13 января 2013

из ссылки / буфера asio говорит: «Буферный объект не имеет права собственности на память, на которую он ссылается. Приложение несет ответственность за обеспечение того, чтобы область памяти оставалась действительной до тех пор, пока она больше не потребуется для ввода-выводаоперация. Когда память больше не доступна, говорят, что буфер признан недействительным.

Для перегрузок boost :: asio :: buffer, которые принимают аргумент типа std :: vector, возвращаются объекты буферааннулируются любой векторной операцией, которая также делает недействительными все ссылки, указатели и итераторы, ссылающиеся на элементы в последовательности (C ++ Std, 23.2.4)

Для перегрузок boost :: asio :: buffer, которые принимают аргументтипа std :: basic_string, возвращенные объекты буфера признаются недействительными в соответствии с правилами, определенными для признания недействительными ссылок, указателей и итераторов, ссылающихся на элементы последовательности (C ++ Std, 21.3). "

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...