boost::asio::buffer exception
Hi, I want to write some data using boost::asio::write(). write() has two arguments, one is the stream to which the data to be written and the other is the data buffer. The data buffer can be created using boost::asio::buffer() function. When I use it this way it works. Then, I have tried to wrap boost::asio::bufffer() in my custom function like this boost::asio::const_buffers_1 MyBuffer(string msg) { return boost::asio::const_buffers_1(boost::asio::const_buffer(msg.c_str(),msg.length())); } The I use this in my asio::write() as booost::asio::write(mySocket, MyBuffer("hai")); This program compiles and runs but it throws an exception called "The system detected an invalid pointer address in attempting to use a pointer argument in a call". I understand that, it is associated with the MyBuffer() function. I have checked it with the buffer() function available in "buffer.hpp". Both are written in the same way, but my function is throwing exception. Could you give some hint? Thanks and Regards, Lloyd
Lloyd Kanakkassery wrote:
Hi,
I want to write some data using boost::asio::write(). write() has two arguments, one is the stream to which the data to be written and the other is the data buffer. The data buffer can be created using boost::asio::buffer() function. When I use it this way it works. Then, I have tried to wrap boost::asio::bufffer() in my custom function like this
boost::asio::const_buffers_1 MyBuffer(string msg) { return boost::asio::const_buffers_1(boost::asio::const_buffer(msg.c_str(),msg.length())); }
The I use this in my asio::write() as
booost::asio::write(mySocket, MyBuffer("hai"));
You are passing a string by value to your function and returning a pointer to its guts. The string needs to have at least as long a lifetime as the write operation.
This program compiles and runs but it throws an exception called "The system detected an invalid pointer address in attempting to use a pointer argument in a call". I understand that, it is associated with the MyBuffer() function. I have checked it with the buffer() function available in "buffer.hpp". Both are written in the same way, but my function is throwing exception. Could you give some hint?
Thanks and Regards, Lloyd
HTH Bill Somerville.
problematic example: class A { public: void func1(){throw bad_alloc();}; void func2() { try { int i; shared_ptr<void> shutdown(static_cast<void*>(0), bind(&A::func1, this)); } catch(...) {}; }; }; int main() { A a1; a1.func2(); }
problematic example: class A { public: void func1(){throw bad_alloc();}; void func2() { try { int i; shared_ptr<void> shutdown(static_cast<void*>(0), bind(&A::func1, this)); } catch(...) {}; }; }; int main() { A a1; a1.func2(); }
2010/11/12 bit bit <g_rambot@hotmail.com>
problematic example:
class A { public: void func1(){throw bad_alloc();};
void func2() { try { int i; shared_ptr<void> shutdown(static_cast<void*>(0), bind(&A::func1, this)); } catch(...) {}; }; };
int main() { A a1; a1.func2(); }
This problem has nothing to do with bind (which doesn't allocate memory). Throwing from a deleter is a no-no (and generally a bad design), since the only time it gets called is by shared_ptr's destructor. Don't do that. This is very likely to be a terminating condition using std::shared_ptr in C++0x.
--
Nevin ":-)" Liber <mailto:nevin@eviloverlord.com> (847) 691-1404
(which doesn't allocate memory).
>>>>>>>>
That's not true. Check this out.. shared_count.hpp template<class P, class D> shared_count( P p, D d ): pi_(0) { try { pi_ = new sp_counted_impl_pd<P, D>(p, d); } catch(...) { d(p); // delete p throw; } } That's what causes the leak.
2010/11/13 bit bit <g_rambot@hotmail.com>
(which doesn't allocate memory).
>>>>>>>>>
That's not true. Check this out..
shared_count.hpp
Please don't quote out of context. I stated that bind doesn't allocate memory. It doesn't. shared_count,hpp is part of shared_ptr, not bind. That's what causes the leak.
You throwing from a deleter which you know is only called from the shared_ptr destructor is what is causing the leak. If you throw from a destructor, all bets are off. -- Nevin ":-)" Liber <mailto:nevin@eviloverlord.com> (847) 691-1404
From: nevin@eviloverlord.com Date: Sat, 13 Nov 2010 11:14:26 -0600 To: boost-users@lists.boost.org Subject: Re: [Boost-users] boost::bind memory leak 2010/11/13 bit bit <g_rambot@hotmail.com> (which doesn't allocate memory).
>>>>>>>>
That's not true. Check this out.. shared_count.hpp Please don't quote out of context. I stated that bind doesn't allocate memory. It doesn't. shared_count,hpp is part of shared_ptr, not bind. That's what causes the leak. You throwing from a deleter which you know is only called from the shared_ptr destructor is what is causing the leak. If you throw from a destructor, all bets are off. -- Nevin ":-)" Liber <mailto:nevin@eviloverlord.com> (847) 691-1404 _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users Throwing
so you are saying that the leak cannot be prevented from inside the shared_ptr? What I am doing, is having a method2 execute from method1, no matter what happens to method1 (return without problem, thow an exception). void MakeShit() { ........ if (...) throw std::exception(); ..... .. shared_ptr<void> cleanup_shit(static_cast<void*>(0), bind(&Thread::CleanupShit, this)); .... .. return; } I prefer not to make CleanupShit() a no-throw method so that it can report errors using exceptions.What I am trying to make a point at, is that shared_ptr should either prevent the leak in the first place using a second level of ra2 inside it, or at least assert that I am not supposed to throw inside the custom deleter. From: nevin@eviloverlord.com Date: Sat, 13 Nov 2010 11:14:26 -0600 To: boost-users@lists.boost.org Subject: Re: [Boost-users] boost::bind memory leak 2010/11/13 bit bit <g_rambot@hotmail.com> (which doesn't allocate memory).
>>>>>>>>
That's not true. Check this out.. shared_count.hpp Please don't quote out of context. I stated that bind doesn't allocate memory. It doesn't. shared_count,hpp is part of shared_ptr, not bind. That's what causes the leak. You throwing from a deleter which you know is only called from the shared_ptr destructor is what is causing the leak. If you throw from a destructor, all bets are off. -- Nevin ":-)" Liber <mailto:nevin@eviloverlord.com> (847) 691-1404 _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
2010/11/13 bit bit <g_rambot@hotmail.com>
so you are saying that the leak cannot be prevented from inside the shared_ptr?
I'm saying that throwing from a destructor is incredibly bad programming practice, and has been known to be bad programming practice for years (plenty of references on this from the writings of Herb Sutter and Scott Meyers). The destructor for std::shared_ptr will (in all likelihood at this point) be marked noexcept under C++0X, which would terminate your program.
I prefer not to make CleanupShit() a no-throw method so that it can report errors using exceptions.
Good luck with that. Even assuming there is no memory leak, how would you make the following work: void func2() { try { int i; shared_ptr<void> shutdown(static_cast<void*>(0), bind(&A::func1, this)); shared_ptr<void> goodluck(static_cast<void*>(0), bind(&A::func1, this)); } catch(...) {}; };
What I am trying to make a point at, is that shared_ptr should either prevent the leak in the first place using a second level of ra2 inside it, or at least assert that I am not supposed to throw inside the custom deleter.
The latter is obvious from the documentation: ~shared_ptr <file:///opt/local/var/macports/software/boost/1.44.0_0/opt/local/share/doc/boost/libs/smart_ptr/shared_ptr.htm#destructor>(); // never throws -- Nevin ":-)" Liber <mailto:nevin@eviloverlord.com> (847) 691-1404
In general I follow the no-destr-throw rule. But i am trying to keep as much debugging information and if possible even recover. If it's impossible I just assert and terminate the appl. I repeat, it's just for this special case where I need all debugging inf. It's an API and I do not have control over code which is called inside ShutDown so that I can make it no-throw too. void CleanUp throw() { // do whatever }; void ShutDown() { if (uncaught_exception()) { try { // do whatever } catch(...) { assert("screwed"); }; } else { try { // do whatever } catch(...) { // recover code throw; }; }; }; void func2() { try { shared_ptr<void> cleanup (static_cast<void*>(0), bind(&A::CleanUp, this)); // both need to be called shared_ptr<void> shutdown(static_cast<void*>(0), bind(&A::ShutDown, this)); // both need to be called } catch(...) {}; }; Well maybe i just need to delete the uncaught_exception, keep the first if condition and call it a day. Angry API users after that. :D From: nevin@eviloverlord.com Date: Sat, 13 Nov 2010 15:05:57 -0600 To: boost-users@lists.boost.org Subject: Re: [Boost-users] boost::bind memory leak 2010/11/13 bit bit <g_rambot@hotmail.com> so you are saying that the leak cannot be prevented from inside the shared_ptr? I'm saying that throwing from a destructor is incredibly bad programming practice, and has been known to be bad programming practice for years (plenty of references on this from the writings of Herb Sutter and Scott Meyers). The destructor for std::shared_ptr will (in all likelihood at this point) be marked noexcept under C++0X, which would terminate your program. I prefer not to make CleanupShit() a no-throw method so that it can report errors using exceptions. Good luck with that. Even assuming there is no memory leak, how would you make the following work: void func2() { try { int i; shared_ptr<void> shutdown(static_cast<void*>(0), bind(&A::func1, this)); shared_ptr<void> goodluck(static_cast<void*>(0), bind(&A::func1, this)); } catch(...) {}; }; What I am trying to make a point at, is that shared_ptr should either prevent the leak in the first place using a second level of ra2 inside it, or at least assert that I am not supposed to throw inside the custom deleter. The latter is obvious from the documentation: ~shared_ptr(); // never throws -- Nevin ":-)" Liber <mailto:nevin@eviloverlord.com> (847) 691-1404 _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
Thanks, it helped... On 11/12/10, Bill Somerville <bill@classdesign.com> wrote:
Lloyd Kanakkassery wrote:
Hi,
I want to write some data using boost::asio::write(). write() has two arguments, one is the stream to which the data to be written and the other is the data buffer. The data buffer can be created using boost::asio::buffer() function. When I use it this way it works. Then, I have tried to wrap boost::asio::bufffer() in my custom function like this
boost::asio::const_buffers_1 MyBuffer(string msg) { return boost::asio::const_buffers_1(boost::asio::const_buffer(msg.c_str(),msg.length())); }
The I use this in my asio::write() as
booost::asio::write(mySocket, MyBuffer("hai"));
You are passing a string by value to your function and returning a pointer to its guts. The string needs to have at least as long a lifetime as the write operation.
This program compiles and runs but it throws an exception called "The system detected an invalid pointer address in attempting to use a pointer argument in a call". I understand that, it is associated with the MyBuffer() function. I have checked it with the buffer() function available in "buffer.hpp". Both are written in the same way, but my function is throwing exception. Could you give some hint?
Thanks and Regards, Lloyd
HTH Bill Somerville. _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
participants (4)
-
Bill Somerville
-
bit bit
-
Lloyd Kanakkassery
-
Nevin Liber