2011-09-16 8 views
1

QMの固有値問題のためにJacobisメソッドをプログラミングしていますが、C++を始めたばかりですが、ダブルポインターを使用して行列を作成したいのですが、ダブルポインターにアクセスするとセグメンテーションフォールトが発生する

私はmain()を読めない行で混乱させたくありません(他の人はこのコードを読む必要があります)ので、問題をサブ関数に分割したいと考えていました。私はダブルポインタをとり、行列を返す関数を作ったが、なぜ関数の外でそれにアクセスできないのだろうか?私のコードsegfaults(以下に記入)私がしようとすると。 main()の外に行列を構築するにはどうすればよいですか?まだ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; 
    } 
    } 
    //Prints 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; 
} 
+2

値10^-8 'pow'を使用して計算されていませんが、その代わりに一定' 1E-8' –

答えて

2
//This part segfaults 
    for(i=0; i<N; i++) 

あなたが参照することにより(makematrixの内側に修正された)値でdouble **Aを渡すとされていない、ので。関数の署名を次のように変更してください:

void makematrix(int N, double **&A) 
...       ^^^ pass by reference 
+0

私は間違っていた、あなたは正しい。 – Werolik

+1

どういうわけか私は 'double **&A'がすぐにいつでも美人コンテストに勝つとは思っていません。貧しいヤコビ。 –

1

あなたが関数にAを渡すとき、関数はAコピー上で動作するため。そのコピーをnew配列を指すように設定しますが、元のAには影響しません。

一つの解決策は、次のとおり

double **A; 

makematrix(N, &A); // Pass address of A 

... 

void makematrix(int N, double ***A) 
{ 
    (*A) = new double*[N]; 
    // etc. 
} 

機能は、原稿を変更できるように、すなわち、Aのアドレスを渡します。

注:トリプルポインタを必要とすると、おそらく設計上の問題が発生します。特にC++で。

3

戻ること:メインで

double** makematrix(int N) { 
    double **A = new double*[N]; 
    ... 
    return A; 
} 

...

double **A = makematrix(N); 
+0

のように記述することができると '削除することを忘れないでくださいを参照してください。それはメインです。このような小さなプログラムでは大きな問題ではありませんが、誰がポインターを所有しているのかを覚えておくとよいでしょう。 – DanS

+0

@ダンス:もしあなたがそれをやろうとすれば、i = 0..N-1に対して 'A [i]'も削除するべきです。しかし、率直に言って、バッチ式の単純なプログラムでは、無駄です。 –

0

ポインタを参照渡しする必要があります。 だから次のようになります。この関数は(私は&を追加):Aそう

​​

あなたの変数が変更されます。この方法では、今、出力パラメータです。

+0

参照渡しの署名が間違っています。 – iammilind

+0

私はそれを修正しました、あなたは正しいです。 – Werolik

0

コードをすばやく修正するには、参照渡しの解決策を使用します。これは、トリプルポインタより読みやすいです。

しかし、本当のC++で、かつ偽装されていないCでコード化したい場合は、行列の背後にある二重配列の複雑さを隠すための解決策は、クラスを作成することです。 C++ FAQライトには、問題の広範な記述とそれを解決するためのさまざまなアプローチがあります。 [] http://www.parashift.com/c++-faq-lite/operator-overloading.html#faq-13.10http://www.parashift.com/c++-faq-lite/operator-overloading.html#faq-13.11

関連する問題