2017-03-06 2 views
-2

그래서 저는 C++로 코딩을 연습하고 있으며 관련 오버로딩 된 연산을 사용하여 (배열로 저장되어있는) 행렬에 대한 클래스를 작성하려고합니다.분할 오류 오버로드 ostream (<<)

나는 클래스를 정의하고 < < 연산자를 오버로드하려고 시도했지만 현재 코드가 세분화 오류 (나는 우분투에서 g ++로 컴파일)를 일으키고 있습니다. 나는 온라인에서 봤고 비슷한 문제를 가진 사람들은 과부하 기능으로 OS를 반환하는 것을 항상 잊어 버리는 경향이있다. 그러나 나는 그렇게 했어. 그래서 내 문제가 무엇인지 몰랐다. 또한 과부하가 걸린 연산자는 세그먼트 오류가 발생하기 전에 여러 번 작동합니다.

도움을 주시면 감사하겠습니다. 당신은 그것을있는 그대로 개인 회원 columns 또는 rows에 액세스 할 수 있기 때문에 기능 클래스 행렬의 friend을해야

#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() 프로그램으로 얼굴이 평평해질 수 있습니다. '{행렬 m (1,2); matrix m2 = m;}' – PaulMcKenzie

답변

-1

:

여기 내 코드입니다. 오버로드하는 동안 일반적인 실수는 operator<<operator>>입니다. friend을 잊지 마세요.

+0

연산자 <<가 친구가되어야한다는 것은 실제로 매우 드뭅니다.이 경우에는 그렇지 않습니다. 클래스는 정상적인 자유 함수로이를 구현하기 위해 적절한 접근 자 기능을 갖고있는 것으로 보입니다. –

+0

나는 선언을 놓쳤다, 사과. – jiveturkey

2

매트릭스의 한계를 벗어나는 것처럼 보입니다.

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

하지만 array[3] 4 요소 : 당신은 배열이 3 개 요소가있는 경우

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

, 이것은 당신이이 3 개 요소를 액세스 할 수 있습니다 ... ij에 대한 +1 제거해야

segmentation fault을 얻었 으면 gdb 또는 valgrind과 함께 프로그램을 실행해야합니다. 이러한 도구는 종종 코드에서 메모리 액세스 오류의 근본 원인을 파악하는 데 매우 중요한 정보를 제공합니다.

+0

배열의 길이는 4입니다. 이것은 세분화 오류가 발생하기 전에 ostream이 여러 번 사용되고 예상대로 4 개의 요소를 출력한다는 사실에 의해 확인됩니다. – user7631642

+0

예를 들어'3'을 썼습니다. 배열의 길이가 4라면, 5 번째 요소 ('array [4]')에 접근하려고 시도하고있다. 분할 오류는 자동이 아닙니다. 귀하의 프로그램은 충돌없이 여러 번 실행될 수 있습니다. 그렇다고해서 위험한 일을하지는 않습니다. 이 질문의 범위를 벗어나는 많은 조건에 달려 있습니다. – SegFault

관련 문제