2011-03-20 55 views
0

嘿,這對我來說確實是一個棘手的問題。使用二維指針陣列時的分段錯誤

的main.cpp

#include <stdlib.h> 
#include <iostream> 
#include "Matrix.h" 

int main(int argc, char** argv) { 
    // Dummy matrix 
    double row1[3] = {3, -1, -2}; 
    double col1[3] = {4, 3, 1}; 
    // Initialize matrix with 4 x 2 dimensions 
    Matrix<double> *m = new Matrix<double>(1, 3); 
    Matrix<double> *n = new Matrix<double>(3, 1); 
    Matrix<double> *mn; 
    // Set each row or column 
    m->set_row(row1, 0); 
    n->set_col(col1, 0); 
    std::cout << "Matrix M: \n"; 
    m->print(); 
    std::cout << "Matrix N: \n"; 
    n->print(); 
    std::cout << "Matrix MN: \n"; 
    mn = m->mult(n); 
    mn->print(); 
    return (EXIT_SUCCESS); 
} 

matrix.h

/* 
* File: Matrix.h 
* Author: charles 
* 
* Created on March 16, 2011, 12:45 AM 
*/ 
#ifndef _MATRIX_H_ 
#define _MATRIX_H_ 

template <typename T> 
class Matrix { 
public: 

    Matrix(int _r, int _c){ 
     // Set row and column size, then initialize matrix 
     _rows = _r; 
     _cols = _c; 
     _matrix = new T * [_rows]; 
     for(int i = 0; i < _rows; ++i){ 
      _matrix[i] = new T [_cols]; 
     } 
    } 

    virtual ~Matrix(){ 
     // Delete everything 
     for(int i = 0; i < _cols; ++i){ 
      delete[] _matrix[i]; 
     } 
     delete[] _matrix; 
    } 

    // Get number of rows 
    unsigned int get_rows(){ 
     return _rows; 
    } 

    // Get number of columns 
    unsigned int get_cols(){ 
     return _cols; 
    } 

    // Returns the row from _matrix as an array 
    T* get_row(int _r){ 
     T* _t = new T [_cols]; 
     for(int i = 0; i < _cols; ++i){ 
      _t[i] = _matrix[_r][i]; 
     } 
     return _t; 
    } 

    // Returns the column from _matrix as an array 
    T* get_col(int _c){ 
     T* _t = new T [_rows]; 
     for(int i = 0; i < _rows; ++i){ 
      _t[i] = _matrix[i][_c]; 
     } 
     return _t; 
    } 

    T get_elem(int _r, int _c){ 
     return _matrix[_r][_c]; 
    } 

    // Set a specific row with an array of type T 
    void set_row(T _t[], int _r){ 
     for(int i = 0; i < _cols; ++i){ 
      _matrix[_r][i] = _t[i]; 
     } 
    } 

    // Set a specific column with an array of type T 
    void set_col(T _t[], int _c){ 
     for(int i = 0; i < _rows; ++i){ 
      _matrix[i][_c] = _t[i]; 
     } 
    } 

    // Set a specific index in the matrix with value T 
    void set_elem(T _t, int _r, int _c){ 
     _matrix[_r][_c] = _t; 
    } 

    // Test to see if matrix is square 
    bool is_square(){ 
     return (_rows == _cols); 
    } 

    // Print contents of matrix for debugging purposes 
    void print(){ 
     for(int i = 0; i < _rows; ++i){ 
      for(int j = 0; j < _cols; ++j){ 
       std::cout << _matrix[i][j] << " "; 
      } 
      std::cout << "\n"; 
     } 
    } 

    T comp_mult(int _r, T* _c){ 
     T temp; 
     for(int i = 0; i < _cols; ++i){ 
      std::cout << "Comp " << i << "\n"; 
      if(i == 0) temp = _matrix[_r][i] * _c[i]; 
      else temp += _matrix[_r][i] * _c[i]; 
     } 
     return temp; 
    } 

    // Add one matrix to another and return new matrix 
    Matrix* add(Matrix* _m){ 

     // Cannot add matrices if they do not have the same dimensions 
     if(!(_rows == _m->get_rows() && _cols == _m->get_cols())){ 
      std::cout << "Not equal!"; 
      return NULL; 
     } 
     else{ 
      Matrix<T>* _t = new Matrix<T>(_rows, _cols); 
      for(int i = 0; i < _rows; ++i){ 
       for(int j = 0; j < _cols; ++j){ 
        _t->set_elem(_matrix[i][j] + _m->get_elem(i, j), i, j); 
       } 
      } 
      return _t; 
     } 
    } 

    // Multiply two matrices and return new matrix 
    Matrix* mult(Matrix* _m){ 
     // If dimensions are not compatible return NULL 
     if(_cols != _m->get_rows()){ 
      return NULL; 
     } 
     else{ 
      Matrix<T>* _t = new Matrix<T>(_rows, _m->get_cols()); 
      // Print out dimensions 
      // std::cout << "Dimensions: r = " << _t->get_rows() << " c = " << _t->get_cols() << "\n"; 
      // Each row of _t 
      for(int i = 0; i < _t->get_rows(); ++i){ 
       // Each value in each row of _t 
       for(int j = 0; j < _t->get_cols(); ++j){ 
        T temp; // Temp variable to hold value for _t[i][j] 
        // Each row in _matrix 
        std::cout << "Loop i:" << i << "\n"; 
        temp = this->comp_mult(i, _m->get_col(j)); 
        std::cout << "loop j: " << j << "\n"; 
        std::cout << "TEMP = " << temp << "\n"; 
        _t->set_elem(temp, i, j); // this is where i segfault 
       } 
      } 
     } 
    } 

    // Multiply entire matrix by number and return new matrix 
    Matrix* scalar(T _n){ 
     Matrix<T>* _t = new Matrix<T>(_rows, _cols); 
     for(int i = 0; i < _rows; ++i){ 
      for(int j = 0; j < _cols; ++j){ 
       _t->set_elem(_matrix[i][j] * _n, i, j); 
      } 
     } 
     return _t; 
    } 

private: 
    unsigned int _rows;   // Number of rows 
    unsigned int _cols;   // Number of columns 
    T** _matrix;    // Actual matrix data 

}; 

#endif /* _MATRIX_H_ */ 

樣本輸出

Matrix M: 
3 -1 -2 
Matrix N: 
4 
3 
1 
Matrix MN: 
Loop i:0 
Comp 0 
Comp 1 
Comp 2 
loop j: 0 
TEMP = 7 
Segmentation fault 

所以我遇到的問題是,當我試圖給一個新的矩陣賦值時遇到了分段錯誤。這對我來說沒有任何意義,因爲我已經初始化了一個新的矩陣,我試圖分配一個值,我知道它的大小,我沒有試圖訪問矩陣之外的內存,並且我知道我的臨時變量有一個值。任何人有建議?

+1

你的'get_col'函數是什麼樣的? – Erik 2011-03-20 18:24:26

+0

看起來您已經發布了'Matrix.cpp'並將其標記爲'Matrix.h'。類定義在哪裏? – 2011-03-20 18:27:21

+0

@Erik我現在將發佈matrix.h的完整源代碼:@Ben這是Matrix.h。 – 2011-03-20 18:30:33

回答

3

你忘了從mult()返回_t - 調試器可能給你打電話mn->print()

此外,get_colget_row泄漏內存,當你崩潰不正確的位置,你需要製作一個拷貝構造函數和一個賦值操作符。

+0

+1:好眼睛:-) ...和btw Q.E.D.關於'std :: endl' – 6502 2011-03-20 18:47:54

+0

哇。我不能相信我錯過了這一點。你太棒了。 * facepalm * get_col和get_row如何泄漏內存?一個小小的解釋是非常可怕的:D – 2011-03-20 18:54:24

+0

@Charles Ray:你是''new''''你在兩個函數中都不會'刪除[]'的東西 - 這就是泄漏。 – Erik 2011-03-20 18:55:24

0
_t->set_elem(temp, i, j); // this is where i segfault 

我的第六感告訴我你要走出索引。查看你的索引值!他們是否在限制之內?

實現set_elem()爲:

void set_elem(T _t, int _r, int _c){ 
    if (_ r >= _rows || _c >= _cols) 
      throw std::out_of_range("index out of range"); 
    _matrix[_r][_c] = _t; 
} 
+0

他們是!正如您在示例輸出中看到的那樣,i = 0和j = 0。初始化_t時,我們將其設置爲(1,1)的大小,所以_t [0] [0]應該可以工作。這就是爲什麼我感到困惑:P – 2011-03-20 18:24:54

+0

在回覆您的編輯時,如果有人試圖設置不在矩陣外部的元素,該代碼將不起作用。 (0,0)這是第一個元素,會使這個拋出錯誤。 – 2011-03-20 18:38:06

+0

@Charles:我的意思是'> ='而不是'<'。現在,這是固定的! – Nawaz 2011-03-20 18:39:41