Leaked Mock Objects when using GoogleMock together with Boost::Shared Pointers

Alex picture Alex · Sep 6, 2012 · Viewed 7.2k times · Source

For this special scenario, I am not able to get rid of the leaks.

I get the message of Leaked Mock Objects when executing the test. The concrete Message:

ClassElementFixture.h:102: ERROR: this mock object (used in test ClassElementFixture.initialize) should be deleted but never is. Its address is @0x940a650.

I marked the line to which the error refers. Here a simplified version of my code:

...
class ClassElementFixture: public ::testing::Test
{
    public:
        boost::shared_ptr<fesa::ClassElement> classElement_;
        boost::shared_ptr<fesa::DeviceElementMock> deviceElement_;

        ...

        void SetUp()
        {
            classElement_.reset(new fesa::ClassElement());
        }

        void TearDown()
        {
        }

        void initializeFake()
        {
            fesa::ParserElementFactoryMock factory;
            deviceElement_.reset(new fesa::DeviceElementMock());

            EXPECT_CALL(factory, createDeviceElement(_))
                        .WillOnce(Return(deviceElement1_));
            EXPECT_CALL(*deviceElement_, initialize(_));//Error refers to here

            classElement_->initialize(factory);

            EXPECT_TRUE(Mock::VerifyAndClearExpectations(deviceElement_.get()));
        }
}

I already found Why is GoogleMock leaking my shared_ptr?

at Stack-Overflow, which is related. However the suggestions from there do not fix my problem :X

The only possibility which I found, in order to at least suppress the error is:

Mock::AllowLeak(deviceElement_.get());

However this is not a very clean solution =)

So how to get rid of the leaks properly?

Answer

Chris Drew picture Chris Drew · Oct 25, 2014

If you use smart pointers, you still need to have a clear idea of ownership otherwise you can get poor performance, cyclic dependencies and memory leaks.

I suggest the default choice of smart pointer should be unique_ptr for unique ownership and use raw pointers for observers.

If the observers could potentially outlive the owner then move to one shared_ptr for the owner and weak_ptr for the observers.

Only use "shared" shared_ptr as a last resort when you don't have one clear owner and be careful of cyclic dependencies.