【问题标题】:C++ : Coverity reports leaks for peculiar use of references and containersC++:Coverity 报告因引用和容器的特殊使用而导致的泄漏
【发布时间】:2016-01-04 20:10:58
【问题描述】:

Coverity 报告以下代码的泄漏。我需要一些帮助来理解错误并重新编写此代码以确保没有错误。 (错误在下面的代码中被注释为cmets)

int main()
{
    ...
    B* b = ...
    //  (1) Coverity: Storage is returned from 
    //      allocation function operator new
    //  (2) Coverity: Assigning ...
    A* a = new A();

    // (3) Coverity: noescape: Resource a is not freed 
    //     or pointed-to in add_a_to_b    
    b->add_a_to_b( *a );
    ...

   // (4) Coverity: Resource leak: Variable a going out 
   //     of scope leaks the storage it points to.
}

class B {
public:
    std::vector<A> a_vector;
    void add_a_to_b( const A& a )
    {
       a_vector.push_back( a );
    }

-- 编辑 ---

我有一个关于 B::add_a_to_b 函数的特殊问题,这可能反映了我对引用的不完整理解:a_vector 是存储对 A 的引用还是创建传递给 add_a_to_b 的对象的副本?

【问题讨论】:

  • b-&gt;add_a_to_b( *a ); 这不存储指针。这确实是b-&gt;add_a_to_b( a );,但随后,您将不得不更改add_a_to_b 的定义(或创建一个带指针的重载)。
  • @PaulMcKenzie 因此,即使 add_a_to_b 将引用作为参数,a_vector 也会存储提供给它的对象 A 的副本?
  • vector::push_back 函数接受一个值并创建一个与您传递给它的值相同的新对象。
  • 是的。副本存储在向量中。如果它是vector&lt;A*&gt;,那么仍然会制作副本,但正在制作的副本是指针的副本。
  • 如果 A 自己进行任何资源管理,这会使复制变得昂贵,如果 A 有移动构造函数,请考虑使用 emplace_back(std::move(a))。

标签: c++ memory-leaks coverity


【解决方案1】:

您有内存泄漏,因为您调用了new 而您没有调用delete。此外,您没有理由调用new 或动态分配。您可以简单地自动分配a。这同样适用于b

B b;
A a;

...   
b.add_a_to_b(a); // b stores a copy of `a`.

【讨论】:

    【解决方案2】:

    嗯。您为 a 分配内存,但从不使用 delete。

    对于每一个新的必须有一个删除。

    delete a; // Do this when you don't need a anymore.
    

    你也可以这样做 - a = nullptr;避免悬空指针。

    编辑:

    您应该学习如何使用智能指针。它们相当容易学习,您不必担心使用 new 和 delete,它会处理删除。

    阅读这篇文章 - Wiki & What is a smart pointer and when should I use one?

    【讨论】:

    • 真正的解决方案是不要new 任何东西。
    • @juanchopanza 是的,我想让这段代码达到不“新”的程度。请参阅我上面的编辑问题。谢谢
    • 是的,当然。但是 99/100 的大学仍然在教新的和删除的,所以大多数学生最终会使用一段时间。
    • 我对此表示怀疑。无论如何,您都可以利用这个机会向他们展示如何正确地做到这一点。
    • @unshul STL 容器按值存储。
    猜你喜欢
    • 1970-01-01
    • 2012-10-06
    • 1970-01-01
    • 1970-01-01
    • 2011-05-22
    • 1970-01-01
    • 2021-07-03
    • 1970-01-01
    • 2013-05-26
    相关资源
    最近更新 更多