The Software Purist |

Archive for March 2013

Mar/13

20

Dangerous Memory Leak in TR1 shared_ptr class

I encountered a major/dangerous memory leak using std::tr1::shared_ptr. There is an edge case which will not delete the memory nor call the destructors. I’ll demonstrate:

Assume MessageFactory::GetMessage() returns a raw pointer of type IMessage for illustration purposes.


#include "IMessage.h"

...

for (size_t index = 0; index < 100; ++index) { std::tr1::shared_ptr pMessage(MessageFactory::GetMessage());
MessageFactory::ProcessMessage(pMessage.get());
}

This deletes the memory just fine. However, note that this block of code is actually not calling any members, so a forward declaration could also be used. So, instead:


class IMessage;

...

for (size_t index = 0; index < 100; ++index) { std::tr1::shared_ptr pMessage(MessageFactory::GetMessage());
MessageFactory::ProcessMessage(pMessage.get());
}

It actually does not have a definition for the destructor here, so it appears to simply skip over it altogether, and with it, it doesn’t call the destructors of the member variables, thus initiating a chain of some very dangerous leaks.

Conversely, in this same example, if we use boost::shared_ptr instead, it knows it won’t be able to call the destructor, so it fails to compile:


class IMessage;

...

for (size_t index = 0; index < 100; ++index) { boost::shared_ptr pMessage(MessageFactory::GetMessage());
MessageFactory::ProcessMessage(pMessage.get());
}


Error 1 error C2027: use of undefined type 'IMessage' c:\dev\common\3rdparty\boost_1_49_0\boost\checked_delete.hpp 32 SharedPtrLeakTest
Error 2 error C2118: negative subscript c:\dev\common\3rdparty\boost_1_49_0\boost\checked_delete.hpp 32 SharedPtrLeakTest

The ideal solution in this case would’ve been boost::scoped_ptr, which produces the same error messages.

Conclusion: We should not use std::tr1::shared_ptr, as the Microsoft implementation appears to be broken. It should not allow compilation for this invalid case. Please use the boost smart pointers (shared_ptr, scoped_ptr, shared_array, scoped_array, weak_ptr) until further notice instead of std::tr1::shared_ptr.

No tags

Mar/13

15

New Server

Hi all. SoftwarePurist is back. We have new hosting and spam filters, so hopefully this should clean up the blog. I plan to be more active and have some new material scheduled, so stay tuned!

No tags

Theme Design by devolux.nh2.me