Boost logo

Boost Users :

Subject: Re: [Boost-users] Force boost::asio::buffer to copy by value.
From: Lars Viklund (zao_at_[hidden])
Date: 2011-05-04 10:35:51


On Wed, May 04, 2011 at 01:07:35PM +0300, Slav wrote:
> Hello. I use boost::asio::buffer to send a message using
>
> void Send(const std::string& messageData)
> {
> socket.async_write(boost::asio::buffer(messageData), ...);
> }
>
> And encounter "string iterator not dereferencable" runtime error somewhere
> within io_service' thread. When I create objects' variable to store message
> data for the buffer:
>
> void Send(const std::string& messageData)
> {
> this->tempStorage = messageData;
> socket.async_write(boost::asio::buffer(this->tempStorage), ...);
> }
>
> the error is never occured. std::string (to which messageData is referenced
> to) is freed almost right after Send() calling - does boost::asio::buffer
> stores just a reference to object? If so, how can I force it to store the
> data by value?

If it did, it would be completely useless as you do not have access to
any of the buffers in your completion handler.

The way to use buffer() is to pass in references to storage that you
guarantee the lifetime of in some other way.

You can either have it stored in an external object, or store it in
`this' as you did, or by binding it into the completion handler function
object itself.

--8<--
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));
}
--8<--

This ensures that the lifetime of the buffer data is at least as long as
the completion handler exists.

-- 
Lars Viklund | zao_at_[hidden]

Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net