首页 > 解决方案 > 现代 C++ 使内存泄漏更难发现

问题描述

您应该如何测试现代 C++ 的内存泄漏?

输出单元测试用例通常如下所示:

TestCase {
  Instantiate testObject
  testObject->AllocateSomeResources
  testObject->PerformATest
  testObject->DeallocateResources
  Destroy testObject
}

我们使用 valgrind 来检测内存泄漏。new如果使用and完成资源分配,这非常有效delete,但是当资源作为智能指针存储在标准容器中时,testObject 销毁时的自动清理会阻止我们发现错误。

系统上线时。由于错误的释放过程,资源容器可能会随着时间的推移而增长。new如果使用and完成分配,这将是微不足道的delete

是否有任何技术可以弥补现代 C++ 的这一方面?

想法:

显然我看到了标准容器和智能指针的好处,对点击诱饵标题感到抱歉

编辑

一个例子:

class A {
  int* resource;
  public:
    void allocate(){ resource = new int; }
    void deallocate(){ /*delete resouce;*/ }
};

class B {
  std::unique_ptr<int> resource;
  public:
    void allocate(){ resource = std::make_unique<int>(); }
    void deallocate(){ /*resource.reset();*/ }
};

A 类和 B 类都有相同的缺陷。deallocate 函数中的一个错误使它们在调用 deallocate 后持有不需要的内存。对于 A 类,这是一个“实际泄漏”,并且在单元测试中使用 Valgrind 检测是微不足道的。对于 B 类,我只能通过将私有资源公开为公共来检测单元测试中的缺陷,我不想这样做。这个问题与 Valgrind 无关,而是是否有模式可以帮助我获得与 Valgrind 和 A 类相同质量的产品,但使用标准容器和智能指针来存储我的私有资源。

所涉及的对象可以存活数周,在此期间分配的资源数量不同。

标签: c++unit-testingc++11smart-pointers

解决方案


您还可以Instantiate在单​​元测试中测试单个方法,而不是一次测试所有方法。独立运行每个测试。然后,您可能能够在每个单独的方法中找到泄漏。

让所有析构函数测试分配的资源。这将对生产代码库产生相当大的影响,只要调用 delete 或对象超出范围,就会调用您的析构函数。似乎不需要明确地测试它们。


推荐阅读