2011-09-16 42 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++) 

因爲,你是路過值double **A(這是內部makematrix修改),而不是引用。改變你的功能簽名以下,它應該工作:

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

@DanS:如果你打算這麼做,那麼你應該'刪除A [i]'i = 0..N-1。但坦率地說,這是一個簡單的批處理式程序的浪費。 –

0

我假設你應該通過參考指針作爲參數。 因此函數應該是這樣的(我增加了一個&):

​​

這樣你的變量將被改變,所以現在是一個輸出參數。

+0

通過引用傳遞錯誤的簽名。 – iammilind

+0

我糾正它,你是對的。 – Werolik

0

要快速修復您的代碼,請使用傳遞引用解決方案,它比三指針更容易閱讀。但是,如果你想用真正的C++代碼,而不是僞裝的C代碼,隱藏在你的矩陣後面的double數組的複雜性的解決方案是創建一個類。 C++ FAQ Lite對你的問題有一個廣泛的描述,以及解決它的不同方法。見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