我有一个带有双指针成员的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不知道所有权的这种变化。
答案 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个场景;你已经有效地将它们融入了相同的设计中。