Segfault when using boost::shared_ptr with GMock

1,072 views
Skip to first unread message

Steve Fox

unread,
Nov 10, 2010, 6:42:31 PM11/10/10
to Google C++ Mocking Framework
I have a test program that I did both with regular pointers and again
with boost::shared_ptr. The former runs just fine, but the latter
always segfaults. Finally, I redid the test with boost::shared_ptr but
no GMock and that worked fine.

I was using a system installed copy of gmock, but get the same results
when I use a manually built library (following the steps in the
README).

I only saw one other post in the archive referring to using
boost::shared_ptr, but I think I'm doing it right. I'm fairly
inexperienced with C++ so I hope I'm not doing something obviously
wrong.

Regular pointers with GMock
===========================================================
#include <gtest/gtest.h>
#include <gmock/gmock.h>

class Bear {
public:
virtual ~Bear() {}
virtual void Roar() = 0;
};

class MockBear: public Bear {
public:
MOCK_METHOD0(Roar, void());
};

class Zoo {
public:
Zoo (Bear* bear) : mBear(bear) {}
void listen () { mBear->Roar(); }
private:
Bear* mBear;
};

TEST(BearTest, TestRoar) {
MockBear bear;
Bear* b = &bear;

EXPECT_CALL(bear, Roar());

Zoo z(b);
z.listen();
}

int main(int argc, char** argv) {
::testing::InitGoogleMock(&argc, argv);
return RUN_ALL_TESTS();
}

boost::shared_ptr with GMock
===========================================================
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include <boost/shared_ptr.hpp>
using boost::shared_ptr;

class Bear {
public:
virtual ~Bear() {}
virtual void Roar() = 0;
};

class MockBear: public Bear {
public:
MOCK_METHOD0(Roar, void());
};

class Zoo {
public:
Zoo (shared_ptr<Bear>& bear) : mBear(bear) {}
void listen () { mBear->Roar(); }
private:
shared_ptr<Bear> mBear;
};

TEST(BearTest, TestRoar) {
shared_ptr<MockBear> bear(new MockBear);
shared_ptr<Bear> b(b.get());

EXPECT_CALL(*bear, Roar());

Zoo z(b);
z.listen();
}

int main(int argc, char** argv) {
::testing::InitGoogleMock(&argc, argv);
return RUN_ALL_TESTS();
}

boost::shared_ptr without GMock
===========================================================
#include <gtest/gtest.h>
#include <boost/shared_ptr.hpp>
using boost::shared_ptr;

class Bear {
public:
void Roar() { std::cout << "Roar!\n"; }
};

class Zoo {
public:
Zoo (shared_ptr<Bear>& bear) : mBear(bear) {}
void listen () { mBear->Roar(); }
private:
shared_ptr<Bear> mBear;
};

TEST(BearTest, TestRoar) {
shared_ptr<Bear> bear(new Bear);

Zoo z(bear);
z.listen();
}

int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

Chris Pickel

unread,
Nov 10, 2010, 7:46:52 PM11/10/10
to Steve Fox, Google C++ Mocking Framework
On Wed, Nov 10, 2010 at 18:42, Steve Fox <li...@thefoxhome.net> wrote:
>    shared_ptr<MockBear> bear(new MockBear);
>    shared_ptr<Bear> b(b.get());

This here is your problem: both 'bear' and 'b' claim ownership over
the object, and both attempt to delete it at the end of the test. If
you replace this with:

MockBear* bear = new MockBear;
shared_ptr<Bear> b(bear);

then your test should pass. Alternately, this may be possible with
shared_ptr<>, but I'm not sure:

shared_ptr<MockBear> bear(new MockBear);
shared_ptr<Bear> b = bear;

Steve Fox

unread,
Nov 10, 2010, 10:21:29 PM11/10/10
to Chris Pickel, Google C++ Mocking Framework
On Wed, Nov 10, 2010 at 6:46 PM, Chris Pickel <sfi...@gmail.com> wrote:
> On Wed, Nov 10, 2010 at 18:42, Steve Fox <li...@thefoxhome.net> wrote:
>>    shared_ptr<MockBear> bear(new MockBear);
>>    shared_ptr<Bear> b(b.get());
>
> This here is your problem: both 'bear' and 'b' claim ownership over
> the object, and both attempt to delete it at the end of the test.  If
> you replace this with:

That seems so obvious now that you say it. :) I can see both
destructors are going to try cleaning it up.

>  MockBear* bear = new MockBear;
>  shared_ptr<Bear> b(bear);
>
> then your test should pass.  Alternately, this may be possible with
> shared_ptr<>, but I'm not sure:
>
>  shared_ptr<MockBear> bear(new MockBear);
>  shared_ptr<Bear> b = bear;

Both of these work.

Many thanks for your help Chris!

Reply all
Reply to author
Forward
0 new messages