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

3

8

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?

Porter answered 6/9, 2012 at 8:29 Comment(4)
I use google-mock v1.6.0 and as well google-test v1.6.0Porter
have you tried to reset() the shared_ptrs in TearDown()?Anamariaanamnesis
Do you have a cycle in your shared_ptr relationships? There's a known issue with shared pointers where cycles can lead to leaks.Interwork
I just saw your comments ... sorry for my long response-time(I have to enable email-notification). Since I posted the problem, the implementation of the used classes has changed. So I am not able to reproduce the bug any more :X I just removed all the Mock::AlowLeak, and things work fine now. I think it realy could be caused by a circular dependency ... thinks like that were used in the old code .. so anyhow, thanks for your help!Porter
M
3

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.

Meow answered 25/10, 2014 at 7:8 Comment(0)
S
2

Don't use shared pointers. Or if you really have to use them make sure they reach back to 0 and get destroyed at the end of the test.

Selfsacrifice answered 27/11, 2013 at 21:51 Comment(0)
I
2

It's an old question, but I don't see anyone mentioning the solution I just found.

I saw the same error until I added a virtual destructor to the class I was mocking. In your case, make sure you've got a virtual destructor on ParserElementFactoryMock. Makes sense, as without the virtual destructor the mock object will not free their resources when going out of scope.

Inflationary answered 8/3, 2016 at 23:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.