2011-12-11 10 views
0

私は数学プロジェクト用の行列クラスを作成しています。私が書いたコピーコンストラクターが1つの関数で失敗しましたが、別の関数で成功したという奇妙な問題があります。同一。私はgdbでそれを実行し、コピーコンストラクタは実行されますが、何らかの理由でそれが終了した後は値が割り当てられません。ここでコピーコンストラクターが失敗し、同じ状況で成功する

は、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) 

あなたが見ることができるように、結果の値は、のようにした後、コンストラクタの前に同じです。

#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; 
} 

EDITは:()

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しない:ここマトリックスコードです。これがなぜ起こっているのか?

EDIT:マトリックスコード

+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

関連する問題