2011-12-11 3 views
0

저는 수학 프로젝트 용 행렬 클래스를 작성하고 있습니다. 필자가 작성한 복사 생성자가 한 함수에서 실패하지만 다른 함수에서 성공하고 이상하게 보이는 이상한 문제가 있습니다. 같은. 내가 gdb를 통해 그것을 실행하고 복사 생성자를 실행하지만 어떻게 든 그냥 끝나면 값을 할당하지 않습니다. 시피복사 생성자가 실패하고 동일한 상황에서 성공 함

(gdb) break main.cpp:20 
Breakpoint 1 at 0x8048913: file main.cpp, line 20. 
(gdb) run 
Starting program: /home/ian/Documents/math471/src/compress 
printing 
1 1 1 1 
1 2 3 4 
1 3 5 7 
1 4 7 10 
printing 
1 1 1 1 
1 2 3 4 
1 3 5 7 
1 4 7 10 
printing 
1 1 1 1 
1 2 3 4 
1 3 5 7 
1 4 7 10 
printing 
1 1 1 1 
1 2 3 4 
1 3 5 7 
1 4 7 10 

Breakpoint 1, main (argc=1, argv=0xbffff334) at main.cpp:20 
20   tridiagonalize(A); 
(gdb) s 
tridiagonalize (A=...) at tridiagonalize.cpp:10 
10   Matrix result(A); 
(gdb) print result 
$1 = {transposed = false, height = 3903476, width = 0, data = 0x0} 
(gdb) s 
Matrix::Matrix (this=0xbffff23c, A=...) at matrix.cpp:176 
176   height = A.getHeight(); 
(gdb) print height 
$2 = 0 
(gdb) n 
177   width = A.getWidth(); 
(gdb) print height 
$3 = 4 
(gdb) n 
178   data = new double*[height]; 
(gdb) print width 
$4 = 4 
(gdb) n 
179   for(int i = 0; i < height; i++){ 
(gdb) break matrix.cpp:185 
Breakpoint 2 at 0x80492ba: file matrix.cpp, line 185. 
(gdb) c 
Continuing. 

Breakpoint 2, Matrix::Matrix (this=0xbffff23c, A=...) at matrix.cpp:185 
185   transposed = false; 
(gdb) n 
186 } 
(gdb) print transposed 
$5 = false 
(gdb) print this 
$6 = (Matrix * const) 0xbffff23c 
(gdb) print this->height 
$7 = 4 
(gdb) n 
tridiagonalize (A=...) at tridiagonalize.cpp:11 
11   int n = A.getWidth(); 
(gdb) print result 
$8 = {transposed = false, height = 3903476, width = 0, data = 0x0} 
(gdb) 

은 결과의 값이 같은 후 생성자 전에 같다 : 여기

은 GDB에서 출력된다.

#include "matrix.h" 
#include "tridiagonalize.h" 


using namespace std; 

void function(Matrix &A); 

int main(int argc, char** argv){ 

     Matrix A(4, 4); 
     for(int i = 0; i < 16; i++){ 
       A.set(i/4, i%4, (i%4)*(i/4)+1); 
     } 
     function(A); 
     Matrix B = A; 
     A.print(); 
     B.print(); 

     tridiagonalize(A); 
     //A.print(); 

     return 0; 
} 

void function(Matrix &A){ 
     Matrix result(A); 
     A.print(); 
     result.print(); 
} 

Matrix tridiagonalize(Matrix &A){ 

     Matrix result(A); 
     int n = A.getWidth(); 
     cout << "width: " << n << endl; 
     cout << "width of result: " << result.getWidth() << endl; 
      return result; 
} 

편집 :()

void Matrix::set(int i, int j, double value){ 
     if(transposed){ 
       int tmp = i; 
       i = j; 
       j = tmp; 
     } 
     if(i < 0 || j < 0 || i >= height || j >= width){ 
       cout << "trying to set value outside of matrix" << endl; 
       return; 
     } 
     if(height > 0 && width > 0){ 
       data[i][j] = value; 
     } 
     return; 
} 

void Matrix::print() const{ 
     cout << "printing" << endl; 
     if(!transposed){ 
       for(int i = 0; i < height; i++){ 
         for(int j = 0; j < width; j++){ 
           cout << data[i][j] << " "; 
         } 
         cout << endl; 
       } 
     } 
     else{ 
       for(int i = 0; i < width; i++){ 
         for(int j = 0; j < height; j++){ 
           cout << data[j][i] << " "; 
         } 
         cout << endl; 
       } 
     } 
     return; 
} 

Matrix::~Matrix(){ 
     //cout << "deleting Matrix" << endl; 
     if(data != NULL){ 
       for(int i = 0; i < height; i++){ 
         //cout << data[i] << endl; 
         delete[] data[i]; 
       } 
       //cout << data << endl; 
       delete[] data; 
     } 
} 

double Matrix::get(int i, int j) const { 
     if(transposed){ 
       int tmp = i; 
       i = j; 
       j = tmp; 
     } 
     if(data != NULL && i >=0 && j >= 0 && i < height && j < width){ 
       return data[i][j]; 
     } 
     else{ 
       cout << "error in get" << endl; 
     } 
     return -1; 
} 

int Matrix::getHeight() const { 
     if(transposed){ 
       return width; 
     } 
     else{ 
       return height; 
     } 
} 

int Matrix::getWidth() const { 
     if(transposed){ 
       return height; 
     } 
     else{ 
       return width; 
     } 
} 



Matrix::Matrix(const Matrix& A){ 
     height = A.getHeight(); 
     width = A.getWidth(); 
     data = new double*[height]; 
     for(int i = 0; i < height; i++){ 
       data[i] = new double[width]; 
       for(int j = 0; j < width; j++){ 
         data[i][j] = A.get(i,j); 
       } 
     } 
     transposed = false; 
} 

Matrix Matrix::operator= (Matrix &B){ 
     if(data != NULL){ 
       for(int i = 0; i < height; i++){ 
         delete[] data[i]; 
       } 
       delete[] data; 
     } 
     data = NULL; 
     Matrix result(B); 
     return result; 
} 

tridiagonalize 기능과 '기능'기능은 동일하지만, 기능을 설정() 작동 tridiagonalize하지 않습니다 여기에 매트릭스 코드입니다. 왜 이런 일이 일어나고 있는거야?

편집 :

+1

우리가 매트릭스 코드를 볼 수 있습니까? – 111111

+0

결국 리턴 타입 매트릭스 때문일 수 있습니다 ...? – evotopid

+0

행렬 코드가 추가되었습니다. 도와 주셔서 감사합니다. – Ian

답변

2

Matrix::operator=() 할당되어야하는 데이터를 새로 작성하지 않고 다음 이전 data 배열을 자유롭게 제대로 작동되지 않지만, 매트릭스 코드를 말했다.

그것은 오히려 다음과 같아야합니다

Matrix& Matrix::operator= (const Matrix &B){ 
    // Don't do anything if B is the same object 
    if (&B == this) 
     return *this; 

    // delete data, as in the current version 
    if(data != NULL){ 
     ... 
    } 

    // Create new array of arrays, fill with numbers from B 
    data = new double*[B.getHeight()]; 
    ... 

    return *this; 
} 
+1

자기 할당 (http://www.parashift.com/c++-faq-lite/assignment-operators.html#faq-12.1) – Drahakar

+0

고맙습니다. 할당 연산자를 수정했습니다. 나는 그것이 복사 생성자 문제를 해결한다고 생각지 않는다. – Ian

+0

잠깐, 어쩌면 그랬 겠지. 고맙습니다. – Ian

관련 문제