Domanda

I have a class A with a double pointer member

double * _E;

for which memory is allocated in the constructor of the class as

_E(new double)

now the class has to deal with two scenarios. One in which it works by itself, in which case _E is deleted in the destructor. Or another case in which it needs to cooperate with another class B on this same member.

In the latter case, I want to reset the location of _E to another address. For this purpose I have written a member function A::wrap_E

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

where I reset the address of _E to that of E passed by reference to the function (E belongs to B but is not a pointer, that's why I copy its address). So that the two classes can operate in turns on the same address (they do different things) and they are aware of the changes without passing E around. _wrap_E=true is a flag that I use to tell the destructor of A whether it should delete _E any longer: if _E wraps another E then it should not be delete by the destructor because memory has already been deallocated.

The code runs fine but Valgrind complains about a memory leak

==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)

where line 119 of A.h is the line of the constructor where I call new: _E(new double).

Any suggestion on how I could fix this? I considered using shared_ptr but this introduces a problem when _E gets reset to &E because the shared_ptr takes ownership and it tries to delete something that belongs to B, and B is not aware of this change in ownership.

È stato utile?

Soluzione

Since this problem arises from your use of new, the simplest solution would be to... well... not.

Instead of allocating the memory for the double on the heap, you can use an automatic variable so that you don't have to worry about deleteing it at some later point. For example:

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)
    {
    }
}

If you do this, then you no longer have to deal with 2 scenarios; you've effectively funneled them into the same design.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top