Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c++ delete reference

I'm still learning c++ and have a question that may be obvious, or maybe I just don't know what I'm trying to do. I have functions that take a matrix (a class I wrote, which has a properly written destructor) and create a new matrix from it, returning a reference to the new one. I need to iterate possibly tens of thousands of times on these matrices so I need to make sure I don't have any memory leaks. So, the question is, how do I properly delete the matrix I don't need any more in order to make space for the next one? Here's the code I'm trying to get leak-free:

DynamicMatrix<double> x0 = getX0(n);

DynamicMatrix<double>exactU = getExactU(n);

DynamicMatrix<double> b = getB(n) * w;

DynamicMatrix<double> x1 = getX1(x0, b, w, n);

while( !isConverged(exactU,x1,e) ){
    delete x0; //<<<<< This doesn't work. Nor does delete &x0.
    x0 = x1;
    x1 = getX1(x0, b, w, n);
}

Each of the getX() methods creates a pointer to a matrix, and returns a reference to the matrix as in getX0():

DynamicMatrix<double> &getX0(int n){
    DynamicMatrix<double>* mat1 = new DynamicMatrix<double>(n * n,1);
    for (int i = 1 ; i <= n; i++){
        for (int j = 1; j <= n; j++){
            mat1->set((i-1)*n +j, 1, 0);
        }
    }
    return *mat1;
}

So then, calling 'delete X0' errors because it needs a pointer. 'delete &X0' says the pointer being freed was not allocated. What is the correct way to do this? Or am I doing something completely wrong? With matrices too large and with too many iterations, my large hard drive runs out of space which I can only assume means I have memory leaks galore.

like image 472
jakev Avatar asked Jan 21 '23 22:01

jakev


1 Answers

Stroustrup R'lyeh Fhtagn.

Writing MyType myVar = MyFunction() creates a brand new object using a constructor that accepts the return type of myFunction as an argument. Whatever was returned by myFunction is then discarded - in your example, getX0 returns a reference to an object that was allocated dynamically, and is therefore leaked.

Seriously, though - try creating the matrices on the stack (without new) and returning them as-is. Shouldn't cause too much trouble, since they appear to allocate their data dynamically on the inside anyway, and I suspect NRVO would apply to avoid making a copy (the returned matrix would be directly constructed into the appropriate location. The x0 and x1 magic at the bottom can be implemented as follows:

x0.swap(x1);
DynamicMatrix<double> temp = getX1(x0, b, w, n);
x1.swap(temp);

Since a swap operation can be implemented on your dynamic matrix in terms of a pointer swap (which is very fast) instead of an actual data copy, this should be extremely fast.

like image 65
Victor Nicollet Avatar answered Jan 30 '23 06:01

Victor Nicollet