c ++ valgrind内存泄漏,即使内存显然已被释放

时间:2014-05-13 11:52:56

标签: c++ memory-leaks

我有一个带有双指针成员的A类

double * _E;

在类的构造函数中将内存分配为

_E(new double)

现在该课程必须处理两种情况。它本身就可以工作的一种情况,在这种情况下,析构函数中会删除_E。或者另一种情况,它需要与同一成员上的另一个B类合作。

在后一种情况下,我想将_E的位置重置为另一个地址。为此,我编写了一个成员函数A :: wrap_E

void A::wrap_E(double &E){
      double Eval = *_E;
      delete _E;
      _E = &E; //relocate address
      *_E = Eval;
      _wrap_E = true;
  }

我将_E的地址重置为通过引用函数传递的E的地址(E属于B但不是指针,这就是我复制其地址的原因)。这样两个类可以在相同的地址上轮流操作(它们做不同的事情),并且他们知道这些变化而不会传递E。 _wrap_E = true是一个标志,用于告诉A的析构函数是否应该再删除_E:如果_E包装另一个E,那么它不应该被析构函数删除,因为内存已经被释放了。

代码运行良好,但Valgrind抱怨内存泄漏

==5014==  16 bytes in 2 blocks are definitely lost in loss record 48 of 1,413
==5014==    at 0x4C2B1C7: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5014==    by 0x414661F: A::A(BasePotential*, Array<double>, double, double, Array<double>&, Array<double>&, Array<double>&) (A.h:119)

其中A.h的第119行是我称之为new的构造函数的行:_E(new double)。

有关我如何解决这个问题的任何建议?我考虑过使用shared_ptr但是当_E被重置为&amp; E时会引入一个问题,因为shared_ptr取得了所有权并且它试图删除属于B的东西,并且B不知道所有权的这种变化。

1 个答案:

答案 0 :(得分:2)

由于您使用new会产生此问题,因此最简单的解决方案是......好吧......不是。

您可以使用automatic variable代替为堆上的double分配内存,这样您就不必担心稍后会delete使用它。例如:

class Foo
{
    double* _E;
    double _defaultE;

public:
    Foo()
        : _defaultE(0.0)
        , _E(&_defaultE) // Automatic variable, so no "new" or "delete"
    {
    }

    Foo(double* E)
        : _E(E)
    {
    }
}

如果你这样做,那么你不再需要处理2个场景;你已经有效地将它们融入了相同的设计中。