These are the offending lines:
> std::vector<boost::asio::const_buffer> iovec;
> iovec.push_back(boost::asio::const_buffer( msg.c_str(), sz ) );
> connection->write(iovec, boost::bind(&async_hello_world::error, this,
> _1));
>
The problem here is that iovec doesn't own the memory pointed to by
the const_buffer instances. This means you are probably accessing
memory that's uninitialized or that's been re-used or something else.
What happens here is that when you do 'connection->write(...)' it
returns immediately and therefore the string owning the message is
destroyed. By the time the data is read/written to the socket it's
been deleted and therefore you're invoking undefined behavior.
The pattern here should be that you create a per-request object that
knows how to handle the result of connection->write(...) and handles
all the necessary state associated with the transfer. This includes
creating somethings that's reference-counted (in a shared_ptr<...>)
and passing the callback using bind and this reference-counted object.
The alternative to this approach is to just do `connection->write(msg,
boost::bind(&async_hello_world::error, this, _1));` and not have to
worry about the management of the data buffers.
Cheers
--
Dean Michael Berris
Technical Solutions Engineer
Google
What example? Can you point me to where this is? Or are you talking
about the test?
https://github.com/cpp-netlib/cpp-netlib/blob/master/libs/network/test/http/server_async.cpp
If you look closely the string is a _static_ function local variable.
It doesn't change and lasts the program's lifetime. The difference
there is that the string is never copied and doesn't go out of scope
until the application actually exits.
> b)
>
> Upon receipt of a client request and prior to invocation of the
> functor ( asynch_hello_word example ) the destructor is invoked 15
> times. The functor will run (ie Hello World is sent to the client)
> and the destructor is invoked twice. A new client request will
> invoke the destructor 15 times, functor will run (i.e Hello World is
> sent to the client) and the destructor is invoked.... repeat.
>
This was a bug fixed by 'idleman' that's now in the 0.9.4 release.
> I added the trivial destructor (see below) to the asynch_hello_world
> example and I was stepping through the code I noticed the behavior -
> which stepping through the code is predicated upon boost libraries
> (boost::_bi::storageN - where N =1,2 and 3, boost::_bi::list,
> boost::bi_bind). Could you elaborate on why I'm seeing multiple
> destructor calls prior to invocation of the handler? Ineterestingly
> enough a destructor call does not result in a call to the
> constructor....so it's unclear what's happening.
>
> ~async_hello_world() {
> std::cout << "." ;
> }
>
This is because the handler object is being copied around in the
completion handlers. This is no longer the case as I mentioned in
0.9.4 -- please use that version instead or if you're using the master
branch then please pull from the latest now.
For the record, this is not an example, this is part of the test
suite. If you want to see an example, look in libs/network/example.
Even if this is the case...
See both of these lines? They're saying the C string "hello_world" and
the response_header array "headers" are function-local static
variables. This means their lifetime is tied to the application's
lifetime, and not the object's lifetime. This is the difference
between your code and this code.
To see how you can approach this problem, look at the fileserver.cpp
example in libs/network/example/http/fileserver.cpp
(https://github.com/cpp-netlib/cpp-netlib/blob/master/libs/network/example/http/fileserver.cpp).
Cheers
--
Dean Michael Berris
www.deanberris.com
--
You received this message because you are subscribed to the Google Groups "The C++ Network Library" group.
To post to this group, send email to cpp-n...@googlegroups.com.
To unsubscribe from this group, send email to cpp-netlib+...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/cpp-netlib?hl=en.