c++ lambda self-passing exception -


when run code, std::bad_functon_call exception. cannot figure out whats reason exception. it's thrown async_receive inside receivecallback. receivecallback cleared out memory before being called?

//callback on connection accepted     std::function<void(const boost::system::error_code& error, tcp::socket* socketptr)> acceptcallback =         [this, onmessagereceivedcallback, acceptcallback](const boost::system::error_code& error, tcp::socket* socketptr)     {         cout<<"accept: "<<error.message()<<endl;          const int buffersize = 100;         char* message = new char[buffersize];          //callback on message received         std::function<void(const boost::system::error_code& error,std::size_t bytes_transferred)> receivecallback =             [message, buffersize, socketptr, onmessagereceivedcallback, receivecallback](const boost::system::error_code& error,std::size_t bytes_transferred)         {             onmessagereceivedcallback(message, bytes_transferred);              socketptr->async_receive(             boost::asio::buffer(message, buffersize),             receivecallback);         };          socketptr->async_receive(             boost::asio::buffer(message, buffersize),             receivecallback);          //create socket next connection         socketptr = new tcp::socket(io_service_);         //continue accepting connections         acceptor_.async_accept(*socketptr, std::bind(acceptcallback, std::placeholders::_1, socketptr)); 

your code undefined behaviour: when lambda captures receivecallback value, receivecallback not yet initialized copy lambda gets garbage (with gcc 4.7 segfault instead of std::bad_function_call). acceptcallback exhibits same problem way.

an apparent solution capture receivecallback reference instead of value, pose problems related lifetime of object (the receivecallback object must stay alive whole duration of i/o operations, gets destroyed exit accept lambda).

it's chicken , egg situation: capture reference won't work because of lifetime issues, need capture value solve that, capture value makes copy of uninitialized object need capture reference solve that. meh.

note receivecallback incorrect in way: capture message value too, means whenever lambda called you'll end not buffer filled boost::asio, copy of buffer made when lambda instantiated (in other words, uninitialized garbage again).


now diagnostic made, how fix , write working code?

in opinion, drop lambdas altogether. write class hold message buffer , onmessagereceivedcallback, , has accept , receive member functions.

depending on exact api of boost::asio may need "wrap" member functions in std::function objects callbacks asio can use (std::mem_fn friend here, don't forget std::bind first argument of resulting std::function object instance of class).


Comments

Popular posts from this blog

SPSS keyboard combination alters encoding -

Add new record to the table by click on the button in Microsoft Access -

CSS3 Transition to highlight new elements created in JQuery -