2011-12-11 87 views
0

我正在寫一個數學項目的矩陣類,我有一個奇怪的問題,我寫的複製構造函數在一個函數中失敗,但在另一個函數中失敗 - 情況看似相同。我已經通過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; 
} 

編輯:這裏是矩陣代碼:

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

最終可能是因爲返回類型Matrix ...? – 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

相關問題