Question

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.

Was it helpful?

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

OTHER TIPS

delete A;

Needs to be

delete[] A;

If you new[] it, you MUST delete[] it. Also, use a vector- they take care of themselves.

vector<vector<double>> matrix;

There are couple of problems with your code.

(1) You are not allocating memory to the pointer members of A. i.e. A[i] are not allocated with new[]. So accessing them is an undefined behavior.

(2) You must do delete[] for a pointer if it was allocated with new[]. In your other function delete A; is wrong. Use delete[] A;

(3) Using new/new[] is not the only way of allocation. In fact you should use such dynamic allocation when there is no choice left. From your code it seems that you are hard coding N=1000. So it's better to use an 2D array.

const int N = 1000;  // globally visible
int main ()
{
  double A[N][N];
  ...
}
void hamiltonian (double (&A)[N][N])
{
  ...
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top