2017-03-06 93 views
-2

所以我正在練習編碼在c + +中,我正試圖編寫一個矩陣(存儲爲數組)的類與相關的重載操作。分割錯誤過載ostream(<<)

我已經儘可能定義類,並試圖超載運算符,但我目前的代碼導致了一個分段錯誤(我在Ubuntu中使用g ++進行編譯)。我在網上看過,有類似問題的人往往會忘記在他們的超載函數中返回os,但是我已經這樣做了,所以我不知道我的問題會是什麼。此外,我的重載操作員在導致分段錯誤之前工作多次。

任何幫助將不勝感激。

這裏是我的代碼:

#include<iostream> 
#include<stdlib.h> // for c style exit 
using namespace std; 

class matrix 
{ 
    // Friends 
    friend ostream & operator<<(ostream &os, const matrix &mat); 
    friend istream & operator>>(istream &is, matrix &mat); 

private: 
    double *mdata; 
    int rows,columns; 
public: 
    // Default constructor 
    matrix(){mdata=0; rows=columns=0;} 
    // Parameterized constructor 
    matrix(int m, int n){mdata = new double[ m*n ]; rows = m; columns = n;} 
    // Copy constructor 
    matrix(matrix &mat) 
    // Destructor 
    ~matrix(){delete[] mdata; cout<<"Destructing array."<<endl;} 
    // Access functions 
    int getrows() const {return rows;} // Return number of rows 
    int getcols() const {return columns;} // Return number of columns 
    int index(int m, int n) const // Return position in array of element (m,n) 
    { 
    if(m>0 && m<=rows && n>0 && n<=columns) return (n-1)+(m-1)*columns; 
    else {cout<<"Error: out of range"<<endl; exit(1);} 
    } 
    double & operator()(int m, int n)const {return mdata[index(m,n)];} 
    // Other access functions go here 
    double & operator[](int i) {return mdata[i];} 
    // Other functions 
    // Copy Assignment operator 
    matrix & operator=(matrix &mat); 
}; 

// Member functions defined outside class 
matrix::matrix(matrix &mat){ 
    rows = mat.getrows(); 
    columns = mat.getcols(); 
    for(int j = 0; j<rows*columns; j++){mdata[j] = mat[j];} 
} 

matrix & matrix::operator=(matrix &mat){ 
    if (&mat == this) return *this; 

    delete[] mdata; rows = 0; columns = 0; 

    rows = mat.getrows(); columns = mat.getcols(); 
    if(rows>0&&columns>0){ 
    mdata = new double[(columns-1) + (rows-1)*columns + 1]; 
    for(int j = 0; j<rows*columns; j++){mdata[j] = mat[j];} 
    } 
    return *this; 
} 


// Overload insertion to output stream for matrices 
ostream & operator<<(ostream &os, const matrix &mat){ 
    for(int j = 0;j<mat.rows;j++){ 
    for(int k = 0;k<mat.columns;k++){ 
     os << mat(j+1,k+1) << " "; 
    } 
    os << endl; 
} 
    return os; 
} 

// Main program 

int main(){ 

    // Demonstrate default constructor 
    matrix a1; 
    cout<<a1; 

    // Parameterized constructor 
    const int m(2),n(2); 
    matrix a2(m,n); 
    // Set values for a2 here 
    a2[0] = 1; a2[1] = 2; a2[2] = 3; a2[3] = 4; 
    // Print matrix a2 
    cout<<a2; 


    // Deep copy by assignment: define new matrix a3 then copy from a2 to a3 
    matrix a3(m,n); 
    cout<<a3; 
    a3=a2; 
    cout<<a3; 
    // Modify contents of original matrix and show assigned matrix is unchanged here 
    a2[0] = 5; 
    cout<<a2; 
    cout<<a3; //here is where segmentation fault occurs 
    return 0; 
} 
+2

我建議先修復複製構造函數和賦值運算符。 – juanchopanza

+0

然後運行一個調試器,因爲你的代碼充滿了微不足道的錯誤。 – juanchopanza

+1

*我已經定義了課程* - 你沒有。這個矩陣類只需要一個兩行的main()程序就可以完全平坦。 '{matrix m(1,2);矩陣m2 = m;}' – PaulMcKenzie

回答

-1

你需要讓該函數的類矩陣的friend,因爲它無法訪問columnsrows,因爲它們是私有成員。典型的錯誤,而超載operator<<operator>>。永遠不要忘記friend

+0

運營商<<需要成爲朋友其實並不常見,在這種情況下它並不是,因爲該類看起來具有適當的訪問器函數,可以將其作爲普通的免費函數來實現。 –

+0

我錯過了宣言,道歉。 – jiveturkey

2

看來你已經超越了矩陣的極限。您應該刪除+1ij ...

for(int j = 0;j<mat.rows;j++){ 
    for(int k = 0;k<mat.columns;k++){ 
     os << mat(j,k) << " "; 
    } 

當一個數組有3個元素,這意味着你可以訪問這些3個要素:

array[0] 
array[1] 
array[2] 

但不array[3]這是4元您的陣列的長度爲3.

作爲一個經驗法則,當您得到segmentation fault時,應該使用gdbvalgrind運行程序。這些工具通常會爲您提供非常有價值的信息,以發現代碼中存儲器訪問錯誤的根本原因。

+0

陣列的長度爲4.這可以通過在發生分段錯誤之前多次使用ostream並按預期輸出4個元素來證實。 – user7631642

+0

我以'3'作爲例子。如果你的數組的長度是4,那麼你試圖訪問第5個元素('array [4]')。分割故障不是自動的,即。你的程序可以運行多次而不會崩潰,這並不意味着你沒有做任何危險的事情。這取決於超出這個問題範圍的許多條件。 – SegFault