Search code examples
c++dynamic-allocationnew-operator

Deleting a doublepointer (matrix)


I am solving a quantum-mech problem which requires me to find some eigenvalues by manipulating some matrices. The specifics of this problem is not relevant, I just need help with the c++ problem, I am new to this language and after a couple of hours I figured any more attempts at solving it myself would be futile and so I turn to you for help.

I have this problem where glibc detects an error at the end of my program and I cannot deallocate properly, it is far too big to copypaste here so I will just replicate the part that actually gives the error.

void hamiltonian(int, double **&);

int i,j;

int main()
{
int N = 1000; double **A;

hamiltonian(N, A);

//Physics here
.
.
.
.
.
//Delete
for(i=0; i<N; i++){delete []A[i];}
delete []A;

return 0;
}

void hamiltonian(int N, double **&A)
{
A = new double *[N];
for(i=0; i<N; i++)
{
A[i] = new double[N];
for(j=0; j<N; j++)
{
if(i==j)A[i][j] = 2;
if(i==j+1 || i==j-1){A[i][j] = 1;}
}
}
}

According to my professor I have to deallocate in the same function as I allocate but I didn't even think about deallocation after being nearly done with my project and so I have to rewrite a lot of code, the problem is that I cannot deallocate A inside the hamiltonian function as I need it in other functions (inside //Physics).

Surely there must be a way around this? Might sound a bit ignorant of me but this sounds like a less efficient design if I have to deallocate in the same function as I allocate.


Solution

  • According to my professor I have to deallocate in the same function as I allocate

    That is pure silliness. Sometimes (almost always) you need to use the allocated struct outside the function. Definitely false for objects, since constructors and destructors are different functions.

    Any way, you can get away without using classes, if you make a Matrix struct and associated newMatrix and deleteMatrix functions :)

    #include <cstddef>
    #include <iostream>
    
    using namespace std;
    
    struct Matrix
    {
        int n;
        int m;
        double** v;
    };
    
    Matrix newMatrix (int n, int m)
    {
        Matrix A;
        A.n = n;
        A.m = m;
        A.v = new double*[n];
        for( int i = 0; i < n; i++ ){
            A.v[i] = new double[m];
        }
        return A;
    }
    
    Matrix newHamiltonianMatrix (int n, int m)
    {
        Matrix A = newMatrix(n, m);
        for( int i = 0; i < A.n; i++ ){
            for( int j = 0; j < A.m; j++ ){
                A.v[i][j] = 0.0;
                if( i == j ){
                    A.v[i][j] = 2.0;
                }
                if( i == j + 1 or i == j - 1 ){
                    A.v[i][j] = 1.0;
                }
            }
        }
        return A;
    }
    
    void deleteMatrix (Matrix A)
    {
        for( int i = 0; i < A.n; i++ ){
            delete [] A.v[i];
        }
        delete [] A.v;
        A.v = NULL;
    }
    
    int main ()
    {
        Matrix A = newHamiltonianMatrix(10, 20);
        for( int i = 0; i < A.n; i++ ){
            for( int j = 0; j < A.m; j++ ){
                cout << A.v[i][j] << " ";
            }
            cout << endl;
        }
        deleteMatrix(A);
    }