gtest基础使用13:Google Test自带示例十:内存泄露检查

一、环境信息

  1. Visual Studio 2019
  2. Windows 10

二、Google Test Sample10

1. 示例概述

1.1 sample10演示了如何通过Google Test的listener API进行内存泄露检查(在示例9中展示了通过 listener API实现控制台的定制化输出)
1.2 示例10中先定义了一个新类,随后通过listener监控类对象的创建和释放,判定是否存在内存泄露的情况

2. 目前的问题(原因已查明,待解决)

2.1 sample10可以编译通过并正常执行,但是代码中的预定目标没有实现:内存泄露报警
原因分析:和示例9一样,需要带参数运行gtest,但是在VS 2019默认条件下,不会带参数执行,也就是说 sample09 sample10均需要带参数独立运行
2.2 示例10也是gtest API的具体使用。这个使用场景可能并不多,目前先不深究,等实际用到了再说

3. 对应的单元测试用例

3.1 sample10详细代码及个人注释如下

#include "pch.h"

// This sample shows how to use Google Test listener API to implement a primitive leak checker.
// sample10:通过gtest的listener接口进行内存泄露检测  //在sample09中,listener接口演示了如何自定义控制台打印输出信息

#include <stdio.h>
#include <stdlib.h>

//#include "gtest/gtest.h"
using ::testing::EmptyTestEventListener;
using ::testing::InitGoogleTest;
using ::testing::Test;
using ::testing::TestEventListeners;
using ::testing::TestInfo;
using ::testing::TestPartResult;
using ::testing::UnitTest;

namespace
{
    // We will track memory used by this class. //跟踪类Water的内存使用
    class Water 
    {
    private:
        static int allocated_;

    public:
        // Normal Water declarations go here.
        // operator new and operator delete help us control water allocation.
        void *operator new(size_t allocation_size) //通过operator重新定义了new:除分配内存空间外,计数器增加
        { //*operator?
            allocated_++;
            return malloc(allocation_size);
        }

        void operator delete(void* block, size_t /* allocation_size */) 
        { 通过operator重新定义了delete:除释放内存空间外,计数器减少
            allocated_--;
            free(block);
        }

        static int allocated() //allocated()函数可以返回当前计数器的值
        { 
            return allocated_;
        }
    };

    int Water::allocated_ = 0;

    // This event listener monitors how many Water objects are created and destroyed by each test,
    // and reports a failure if a test leaks some Water objects.
    // listener用于监控测试中共有多少类对象被创建和删除,如果存在泄漏,则上报失败。通过比对测试前后的类对象数量进行监控
    // It does this by comparing the number of live Water objects at the beginning of a test and at the end of a test.
    class LeakChecker : public EmptyTestEventListener 
    {
    private:
        // Called before a test starts. //测试开始时,读取类Water中计数器的值
        void OnTestStart(const TestInfo& /* test_info */) override 
        { 
            initially_allocated_ = Water::allocated();
        }

        // Called after a test ends. //测试结束后,读取类Water中计数器的值并与初始值相减
        // 若内存不泄露,当前读取的值 一定小于等于 初始值
        void OnTestEnd(const TestInfo& /* test_info */) override 
        { 
            int difference = Water::allocated() - initially_allocated_;

            // You can generate a failure in any event handler except OnTestPartResult.
            // Just use an appropriate Google Test assertion to do it. // << 中的信息在用例执行失败后触发
            EXPECT_LE(difference, 0) << "Leaked " << difference << " unit(s) of Water!";
        }

        int initially_allocated_;
    };

    TEST(ListenersTest, DoesNotLeak) 
    {
        Water* water = new Water;
        delete water;
    }

    // This should fail when the --check_for_leaks command line flag is specified.
    // 
    TEST(ListenersTest, LeaksWater) //只有new分配内存 没有delete释放内存 一定会触发内存泄露
    {
        Water* water = new Water;
        EXPECT_TRUE(water != nullptr);
    }
}  // namespace

int main2(int argc, char** argv) //int main(int argc, char** argv)?
{
    InitGoogleTest(&argc, argv); //InitGoogleTest?

    bool check_for_leaks = false;
    if (argc > 1 && strcmp(argv[1], "--check_for_leaks") == 0) //若用例带参数 --check_for_leaks 执行,check_for_leaks赋值为true
        check_for_leaks = true;
    else
        printf("%s\n", "Run this program with --check_for_leaks to enable "
            "custom leak checking in the tests.");

    // If we are given the --check_for_leaks command line flag, installs the leak checker.
    // 
    if (check_for_leaks) 
    {
        TestEventListeners& listeners = UnitTest::GetInstance()->listeners();

        // Adds the leak checker to the end of the test event listener list,
        // after the default text output printer and the default XML report
        // generator.
        //
        // The order is important - it ensures that failures generated in the
        // leak checker's OnTestEnd() method are processed by the text and XML
        // printers *before* their OnTestEnd() methods are called, such that
        // they are attributed to the right test. Remember that a listener
        // receives an OnXyzStart event *after* listeners preceding it in the
        // list received that event, and receives an OnXyzEnd event *before*
        // listeners preceding it.
        //
        // We don't need to worry about deleting the new listener later, as
        // Google Test will do it.
        listeners.Append(new LeakChecker);
    }
    return RUN_ALL_TESTS();
}

  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值