GoogleTest和内存泄漏问题

12

我很惊讶Google C++测试框架没有显式支持检查内存泄漏。然而,对于Microsoft Visual C++,有一个变通方法,但是对于Linux呢?

如果内存管理对我很重要,那么使用另一个C++单元测试框架是否更好呢?

5个回答

7
如果内存管理对我至关重要,是否最好使用另一个C++单元测试框架?
我不知道C++单元测试,但我使用了Dr. Memory,在Linux、Windows和Mac上都可以使用。如果你有符号,它甚至会告诉你内存泄漏发生在哪一行!非常有用 :D
更多信息http://drmemory.org/

6
即使这个线程非常古老。最近我正在搜索此内容。
我现在想到了一个简单的解决方案(受启发自https://dev59.com/HnbZa4cB1Zd3GeqPG4gP#19315100)。
只需编写以下标头:
#include "gtest/gtest.h"
#include <crtdbg.h>

class MemoryLeakDetector {
public:
    MemoryLeakDetector() {
        _CrtMemCheckpoint(&memState_);
    }

    ~MemoryLeakDetector() {
        _CrtMemState stateNow, stateDiff;
        _CrtMemCheckpoint(&stateNow);
        int diffResult = _CrtMemDifference(&stateDiff, &memState_, &stateNow);
        if (diffResult)
            reportFailure(stateDiff.lSizes[1]);
    }
private:
    void reportFailure(unsigned int unfreedBytes) {
        FAIL() << "Memory leak of " << unfreedBytes << " byte(s) detected.";
    }
    _CrtMemState memState_;
};

然后只需在你的测试中添加本地的MemoryLeakDetector:

TEST(TestCase, Test) {
    // Do memory leak detection for this test
    MemoryLeakDetector leakDetector;

    //Your test code
}

示例:

一个类似这样的测试:

TEST(MEMORY, FORCE_LEAK) {
    MemoryLeakDetector leakDetector;

    int* dummy = new int;
}

生成以下输出:

输入图像描述

我相信有更好的工具,但这是一种非常简单易用的解决方案。


2
我希望你的解决方案能在Linux上运行,但它只能在Windows上运行,因为_CrtMem*是Windows本地API。 - Eugenio Miró

4

"我很惊讶谷歌的 C++ 测试框架不明确支持检测内存泄漏。"

它从未旨在做到这一点。你实际上可以进行一些认证,例如使用 Google Mock 并设置预期的调用(例如析构函数)。但是使用专门针对此方面的工具肯定比你自己编写的任何内容都要好。

"使用其他 C++ 单元测试框架是否更好?"

那么为什么要寻找不同的单元测试框架(也不支持这个功能,至少我不知道有哪个)。

有一些工具,例如 Valgrind,你可以使用并在其控制下运行你的 UnitTester 可执行文件以检测内存泄漏。

注意:
上述建议在 UnitTester 可执行文件中执行此操作将无法捕获代码生成的最终可执行文件中可能出现的所有内存泄漏,但只能帮助发现实际测试代码中的错误/缺陷。


是的,但这涉及在另一个测试框架下运行我的测试,可能太复杂了。 - Andrew
@AndrejsIgumenovs:“可能太复杂了”并不像你想象的那么“复杂”(例如,只需在valgrind下运行UnitTester)。好吧,不同的工具有不同的用途,你可以自由地组合它们以实现你想要分析的目标。 - πάντα ῥεῖ
1
CppUTest可以检测内存泄漏,但它主要用于嵌入式C/C++。 - Technophile
@HCSF,您能否指导或分享一下如何使用标志--gtest.valgrind=true? - Prashant Adlinge
1
@PrashantAdlinge,这样的标志不存在。我的意思是原帖作者正在寻找像--gtest.valgrind这样的标志,而不是在valgrind上运行gtest。 - HCSF
显示剩余2条评论

2

不确定这个方法在2015年是否有效,但自2018年左右起,我们使用带有CLang的sanitizers(包括LeakSanitizer、AddressSanitizer和UndefinedBehavior sanitizer)的GoogleTest。

只需启用sanitizers构建测试,例如基于CMake的项目:

  add_compile_options(-fsanitize=leak,address,undefined -fno-omit-frame-pointer -fno-common -O1)
  link_libraries(-fsanitize=leak,address,undefined)

-1

内存泄漏是由于系统接口的错误使用而导致的,单元测试应该检查在您的测试单元中这些接口是否被正确使用,而不是这些接口的实现特定结果。它应该检查直接由您的单元使用的内存分配和释放接口是否按设计使用。测试系统特定结果将成为组件或集成测试的一部分。在单元测试中,内存管理接口对于测试单元来说是外部的,因此应该使用测试实现进行存根处理。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接