【问题标题】:Leaked Mock Objects when using GoogleMock together with Boost::Shared Pointers将 GoogleMock 与 Boost::Shared Pointers 一起使用时泄漏的模拟对象
【发布时间】:2012-09-06 08:29:53
【问题描述】:

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

我在执行测试时收到 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());

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

那么如何正确地消除泄漏呢?

【问题讨论】:

  • 我使用 google-mock v1.6.0 和 google-test v1.6.0
  • 您是否尝试过重置()TearDown() 中的 shared_ptrs?
  • 你的 shared_ptr 关系中有循环吗?共享指针存在一个已知问题,循环会导致泄漏。
  • 我刚看到你的 cmets ...抱歉我的回复时间长(我必须启用电子邮件通知)。自从我发布问题以来,使用的类的实现已经改变。所以我不能再重现这个错误了:X 我刚刚删除了所有的 Mock::AlowLeak,现在一切正常。我认为这确实可能是由循环依赖引起的......认为旧代码中使用了这样的......所以无论如何,感谢您的帮助!

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


【解决方案1】:

如果您使用智能指针,您仍然需要对所有权有一个清晰的概念,否则您可能会遇到性能不佳、循环依赖和内存泄漏的问题。

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

如果观察者的寿命可能比所有者长,则为所有者移动一个shared_ptr,为观察者移动一个weak_ptr

仅当您没有明确的所有者并注意循环依赖时,才将“共享”shared_ptr 作为最后的手段。

【讨论】:

    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多