将GoogleMock与Boost :: Shared Pointers一起使用时泄露的模拟对象

时间:2012-09-06 08:29:54

标签: c++ memory-leaks shared-ptr googlemock

对于这种特殊情况,我无法摆脱泄漏。

执行测试时,我收到了Leaked Mock Objects的消息。具体消息:

ClassElementFixture.h:102:错误:应删除此模拟对象(在测试ClassElementFixture.initialize中使用)但从不删除。它的地址是@ 0x940a650。

我标记了错误所指的行。 这是我的代码的简化版本:

...
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()));
        }
}

我已经找到了 Why is GoogleMock leaking my shared_ptr?

Stack-Overflow上的

,这是相关的。但是那里的建议并没有解决我的问题:X

为了至少抑制错误,我发现的唯一可能性是:

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

然而,这不是一个非常干净的解决方案=)

那么如何正确摆脱泄漏?

3 个答案:

答案 0 :(得分:3)

如果您使用智能指针,您仍然需要清楚所有权,否则您可能会遇到性能不佳,循环依赖和内存泄漏。

我建议智能指针的默认选择应为unique_ptr以获得唯一所有权,并使用原始指针作为观察者。

如果观察者可能比所有者活得更久,那么为所有者移动一个shared_ptr,为观察者移动weak_ptr

如果您没有一个明确的所有者并且注意循环依赖,请仅使用“共享”shared_ptr作为最后的手段。

答案 1 :(得分:2)

不要使用共享指针。或者如果你真的必须使用它们,请确保它们回到0并在测试结束时被销毁。

答案 2 :(得分:1)

这是一个老问题,但我没有看到有人提到我刚刚找到的解决方案。

我看到同样的错误,直到我向我正在嘲笑的类添加了一个虚拟析构函数。在您的情况下,请确保您在ParserElementFactoryMock上有一个虚拟析构函数。有道理,因为没有虚拟析构函数,模拟对象在超出范围时不会释放资源。