GoogleTest 和内存泄漏

GoogleTest and Memory Leaks

我很惊讶 Google C++ 测试框架没有明确支持检查内存泄漏。但是,Microsoft Visual C++ 有一个解决方法,但是 Linux?

呢?

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

"I'm surprised that Google C++ Testing Framework does not explicitly support checking for memory leaks."

这不是(也从来没有)这样做的目的。 你实际上可以做一些证明,例如使用 google mock 并设置预期调用(例如析构函数)。但是使用专门针对这方面的工具,肯定会比您自己编写的所有东西都做得更好。

"is it better to use another C++ unit-testing framework?"

所以为什么要费心寻找不同的单元测试框架(也不支持这样的功能,至少 none 我知道)。

您可以使用 valgrind 和 运行 您的 UnitTester 可执行文件等工具来检测内存泄漏。

注:
上述使用 UnitTester 可执行文件执行此操作的建议将无法从您的代码生成的最终可执行文件中捕获所有可能的内存泄漏,但只是帮助找到 bugs/flaws 实际上测试代码。

如果内存管理对我来说至关重要,使用另一个 C++ 单元测试框架是否更好?

我不知道 C++ 单元测试,但我使用了 Dr. memory,它适用于 linux windows 和 mac 如果你有符号,它甚至会告诉你内存泄漏发生在哪一行!真的很有用 :D
更多信息 http://drmemory.org/

内存泄漏是系统接口使用不当的结果,单元测试应该检查这些接口是否在被测单元中被正确使用,而不是这些接口的具体实现结果是什么。它应该检查您的单元直接使用的内存分配和释放接口是否按设计使用。测试系统特定结果将是组件或集成测试的一部分。在单元测试中,内存管理接口在被测单元的外部,因此应该用测试实现来剔除。

即使这个线程很旧。我最近在找这个。

我现在想出了一个简单的解决方案(灵感来自 https://whosebug.com/a/19315100/8633816

就写下面的header:

#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;
}

产生输出:

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

不确定这在 2015 年是否有效,但自 2018 年左右以来,我们将 GoogleTest 与 CLang 的消毒剂一起使用,包括 LeakSanitizer、AddressSanitizer 和 UndefinedBehavior 消毒剂。

只需在启用消毒剂的情况下构建测试,CMake-based 项目的示例:

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