Accessing double pointer causes segmentation fault
I am programming Jacobis method for eigenvalue problems in QM and I have just started c++, I want to use double pointers to construct matrices but the physics problem involved requires a lot of code.
I don't want to clutter my main()
with unreadible lines (others will have to read this code..) and so wanted to divide the problem into subfunctions. I made a function that takes a double pointer and returns a matrix, but why can't I access it outside the function? My code segfaults (marked below) when I try to. How do I construct a matrix outside main() while still being able to access it in main()
?
enter code her enter code here
int i, j, k;
//== BEGIN MAIN ==//
int main ()
{
//Constants and variables
double **A;
double epsilon = pow((double)10, double(-8)); //The convergence limit for jacobis method
int N = 10; //Dimension of matrix
char test[] = "test";
cout <<"The inner matrix function:"<<endl;
makematrix(N, A);
cout<<endl<<"The outer matrix function:"<<endl;
//This part segfaults
for(i=0; i<N; i++)
{
cout<<endl;
for(j=0; j<N; j++)
{
cout<<A[i][j]<<" ";
}
}
return 0;
}
//== END MAIN ==//
//==Begin function definitions==//
void makematrix(int N, double **A)
{
//Function for initializing our tridiagonal matrices for jacobis method
A = new double*[N];
for(i=0; i<N; i++)
{
A[i] = new double[N];
}
for(i=0; i<N; i++)
{
for(j=0; j<N; j++)
{
A[i][j] = 0;
}
}
//Pr开发者_如何转开发ints the matrix declared here
for(i=0; i<N; i++)
{
cout<<endl;
for(j=0; j<N; j++)
{
cout<<A[i][j]<<" ";
}
}
cout <<endl;
return;
}
Return it:
double** makematrix(int N) {
double **A = new double*[N];
...
return A;
}
In main...
double **A = makematrix(N);
//This part segfaults
for(i=0; i<N; i++)
Because, you are passing double **A
by value (which is modified inside makematrix
) and not by reference. Change your function signature to following and it should work:
void makematrix(int N, double **&A)
... ^^^ pass by reference
Because when you pass A
into the function, the function operates on a copy of A
. It sets that copy to point at a new
array, but that doesn't affect the original A
.
One solution is:
double **A;
makematrix(N, &A); // Pass address of A
...
void makematrix(int N, double ***A)
{
(*A) = new double*[N];
// etc.
}
i.e. pass the address of A
, so that the function can modify the original.
Note: Any time you end up needing triple pointers, you probably have a design problem. Especially in C++.
I assume you should pass the pointer as parameter by reference. So the function should look like this (I added an &):
void makematrix(int N, double **&A)
This way your variable will be changed, so A is now an output parameter.
To rapidly fix your code, use the pass-by-reference solution, it's easier to read than the triple pointer.
However, if you want to code in real C++, and not in disguised C, a solution to hide the complexity of the double array behind your matrix is to create a class. The C++ FAQ Lite has an extensive description of your problem, and different approaches to solve it. See http://www.parashift.com/c++-faq-lite/operator-overloading.html#faq-13.10 and http://www.parashift.com/c++-faq-lite/operator-overloading.html#faq-13.11
精彩评论