2011-09-10 10 views
2

私は行列オブジェクトのコンストラクタを構築しました。データは構造体valの配列に格納され、配列の位置と値が保持されます。これはコードです:コンストラクタの不明瞭なセグメント化エラー

SparseMatrix::SparseMatrix(const int numRow, const int numCol, vector<double> fill): 
     Matrix(numRow,numCol) 
{ 
    _matrix = new vector<val*>(fill.size()); 
    vector<double>::iterator itr = fill.begin(); 
    for(signed int i=0; i<numRow; i++) 
    { 
     for(signed int j=0; j<numCol; j++, itr++) 
     { 
      if (*itr == 0) 
      { 
       continue; 
      } 
      val *temp = new val; 
      temp->value = *itr; 
      temp->x = i; 
      temp->y = j; 
      _matrix->push_back(temp); 
      cout << "Psition: " << ": " << _matrix->front()->x << //<--ERROR  
      cout << " " << _matrix->back()->y << endl; 
     } 
    } 
} 

私はpush_backが本当に私のために働いていないことを確認するためにちょうど追加しました。 _matrixはヒープ上にあり、そこに保持されているすべての構造体も同様です。すべては 'new'を使用して作成されます。なぜこれがうまくいかないのか分からない。私がそれを読むことができないベクトルに新しい構造体のポインタをプッシュした後の1行(私が言ったようにセグメンテーションフォールト)。

アイデア?ありがとう!

EDIT: 申し訳ありませんが、これはvalgrindののメッセージです:

==13334== Invalid read of size 4 
==13334== at 0x804AEAE: SparseMatrix::SparseMatrix(int, int, std::vector<double,  std::allocator<double> >) (in /home/yotamoo/workspace/ex3/main) 
==13334== by 0x8048C10: main (in /home/yotamoo/workspace/ex3/main) 
==13334== Address 0x8 is not stack'd, malloc'd or (recently) free'd 
==13334== 
==13334== 
==13334== Process terminating with default action of signal 11 (SIGSEGV) 
==13334== Access not within mapped region at address 0x8 
==13334== at 0x804AEAE: SparseMatrix::SparseMatrix(int, int, std::vector<double,  std::allocator<double> >) (in /home/yotamoo/workspace/ex3/main) 
==13334== by 0x8048C10: main (in /home/yotamoo/workspace/ex3/main) 
==13334== If you believe this happened as a result of a stack 
==13334== overflow in your program's main thread (unlikely but 
==13334== possible), you can try to increase the size of the 
==13334== main thread stack using the --main-stacksize= flag. 
==13334== The main thread stack size used in this run was 8388608. 

そして - セグメンテーションフォールトは、最初の反復の間に発生!

+1

を何GDBはあなたを教えたのですか? Valgrind?なぜポインタを格納していますか? –

答えて

4

これは*_matrixを構築するために使用されているstd::vector<val *>コンストラクタである:

explicit vector (size_type n, const val *& value = val *(), const std::allocator<val *>& = std::allocator<val *>()); 

fill.size()からnセットとそのコンストラクタの呼び出しがfill.size()デフォルトに構成val *オブジェクト(すべてNULL)を有する新規std::vector<val *>を作成します。新しいvalポインタをプッシュバックすると、*_matrixfill.size() + 1の要素を持ち、_matrix->front()はまだNULLのポインタです。実際には、NULLを逆参照しています。

あなたはおそらくreserve()メソッドを探しています。

EDIT:改善することができる、私は気づいたいくつかの他のものがあります。

  1. SparseMatrixコンストラクタは値によってfillを取っているが。これは、新しいSparseMatrixを構築するために、doubleオブジェクトのベクトルの完全なコピーが作成されることを意味します。代わりにfillをconst-referenceで渡す必要があります。
  2. STLコンテナイテレータでは、ポストインクリメントの結果を必要としない限り、常にプリインクリメント演算子を使用する必要があります。
  3. 新しいvalオブジェクトの割り当ての1つがstd::bad_alloc例外をスローすると、メモリがリークします。
  4. プールアロケータを使用して、多くのvalオブジェクトを割り当てることを検討してください。いくつかのC/C++ランタイムライブラリの実装(例:OpenBSD)は、メモリ割り当てをランダム化します。ヒープ上に多数の小さなオブジェクトを割り当てると、ヒープの断片化が深刻になる可能性があります。
2

numCol>fill.size()の場合、ループは最後まで実行されません。

0

エラーは、他の人が説明したように、予約してから参照解除するのではなく、nullptrで初期化することです。

また、すべてのアイテムのスペースを予約し、未使用のスペースを解放しないようにしています。スパース配列は、渡された元のベクトルよりも多くのスペースを常に使用します。

これらのアイテムをすべて新しくするべきではありません。値のベクトルを扱う。これにより、コードの例外が安全になります。

また、あなたが記入のアクセスを確認していないという問題もあります。要素の数に少なくともアサルトが必要です。

valは、このような構造体であると仮定すると:

struct val 
{ 
    val(int x, int y, double value):x(x),y(y),value(value){} 
    int x; 
    int y; 
    double value; 
}; 

、その後の改善/修正版は次のようになります。

class SparseMatrix 
{ 
    vector<val> _matrix; 

public: 

    SparseMatrix(const int numRow, const int numCol, vector<double> const& fill) 
    { 
     assert(numCol > 0); 
     assert(numRow > 0); 
     assert(numRow * numCol == fill.size()); 

     int skipped = std::count(fill.begin(), fill.end(), 0.0); 

     _matrix.reserve(fill.size() - skipped); 

     vector<double>::const_iterator itr = fill.begin(); 
     for(int i=0; i<numRow; ++i) 
     { 
      for(int j=0; j<numCol; ++j, ++itr) 
      { 
       if(*itr != 0.0) 
       { 
        _matrix.push_back(val(i, j, *itr)); 
       } 
      } 
     } 
    } 
}; 
関連する問題