5

データ行列を操作するメイン アプリケーションで使用する単純なテンプレート化された Matrix クラスを作成しました。切り捨てられたマトリックス コードは次のとおりです。

template <typename T> 
class Matrix{
   private:
      std::vector<T> matrixRepresentation;
      bool transposed;
  public: 
  Matrix(int r, int c);
  int maxRows;
  int maxCols;
  void setMatrixValue(int row, int col, T val);
  T getMatrixValue(int row, int col);
};

template <typename T>
Matrix<T>::Matrix(int r, int c){
   maxRows = r;
   maxCols = c;
   matrixRepresentation.resize((r+1)*(c+1));
}   

template <typename T>
void Matrix<T>::setMatrixValue(int row, int col, T val){
   matrixRepresentation[row + col*maxCols] = val;
}

template <typename T>
T Matrix<T>::getMatrixValue(int row, int col){
   return matrixRepresentation[row + col*maxCols];
}

ご覧のとおり、2D マトリックスをベクトルとして表現し、その事実を隠すラッパー メソッドを提供しているだけです。スタック変数matrixRepresentationのサイズを変更しても

(r+1)(c+1)

コードの後半でメモリ破損の問題が発生し、valgrind から次のように通知されます。

==3753==    at 0x8049777: Matrix<int>::setMatrixValue(int, int, int) (in a.out)
==3753==    by 0x8049346: DataFile::readAllData() (ina.out)
==3753==    by 0x8049054: DataFile::DataFile(char const*) (in a.out)
==3753==    by 0x804C386: main (in a.out)
==3753==  Address 0x42cc970 is 0 bytes after a block of size 5,600 alloc'd
==3753==    at 0x4026351: operator new(unsigned int) (vg_replace_malloc.c:255)
==3753==    by 0x804A603: __gnu_cxx::new_allocator<int>::allocate(unsigned int, 
            void   const*) (in /a.out)
==3753==    by 0x8049F0D: std::_Vector_base<int, std::allocator<int> 
            >::_M_allocate(unsigned int) (in a.out)
==3753==    by 0x804A181: std::vector<int, std::allocator<int> 
            >::_M_fill_insert(__gnu_cxx::__normal_iterator<int*, std::vector<int, 
            std::allocator<int> > >, unsigned int, int const&) (in a.out)
==3753==    by 0x8049AEF: std::vector<int, std::allocator<int> 
            >::insert(__gnu_cxx::__normal_iterator<int*, std::vector<int, 
            std::allocator<int> > >, unsigned int, int const&) (in a.out)
==3753==    by 0x80499AB: std::vector<int, std::allocator<int> >::resize(unsigned int,
            int) (in a.out)
==3753==    by 0x8049709: Matrix<int>::Matrix(int, int) (in a.out)
==3753==    by 0x80492AD: DataFile::readAllData() (in a.out)
==3753==    by 0x8049054: DataFile::DataFile(char const*) (in a.out)
==3753==    by 0x804C386: main (in a.out)

readAllData() メソッド (このマトリックス クラスのユーザー) は、単純にテキスト ファイルから読み取り、マトリックスに入力しようとしています。

void DataFile::readAllData(){
   int currentValue;
   featureMatrix = new Matrix<int>((theHeader.totalNumSamples),
   (theHeader.numFeatures));

    if (infile.is_open()){
       if (!infile.eof()){
          for (int row=0; row < theHeader.totalNumSamples; row++){
            for (int col=0; col < theHeader.numFeatures; col++){
               infile >> currentValue;
               featureMatrix->setMatrixValue(row, col, currentValue);
             }
          }
       }
       else{
          cout << "EOF reached before we should have been done!  Closing file";
          infile.close();
       }
   }
   else cout << "File not open when attempting to read data";

   infile.close();
}

ヘッダー値は有効です (例: theHeader.totalNumSamples = 15、theHeader.numFeatures = 100)。

これ以上の情報を提供できるかどうか教えてください。

4

3 に答える 3

8

このスニペット (コードに 2 回表示されます):

 [row + col*maxCols]

正しくありません。[row * maxCols + col]または_[col*maxRows + row]

さらに言えば、割り当てる必要はありません。matrixRepresentation.resize((r+1)*(c+1)); 代わりに割り当てることができますmatrixRepresentation.resize(r*c);

極端なケースで計算を行う必要があります (要素へのアクセスなど、(maxRows-1,maxCols-1)目的を理解するために自分でこれをチェックするなど)。

于 2012-04-24T23:40:49.307 に答える
1

これで問題は解決しますか?

template <typename T>
Matrix<T>::Matrix(const int r, const int c) :
   maxRows(r),
   maxCols(c),
   matrixRepresentation((r+1)*(c+1))
{}

解決する場合としない場合がありますが、Matrix.

更新: @ChrisA. の回答の方が優れています。まずそれを試してください。

于 2012-04-24T23:37:15.600 に答える
1

Valgrind の特定の問題が何であるかはわかりませんが、次のことがわかりました。

maxRows = r;
maxCols = c;
matrixRepresentation.resize((r+1)*(c+1));

コンストラクターでは、たとえば 3x3 マトリックスを作成していますが、9 ではなく 16 の場所を割り当てています。これは必ずしも問題ではありませんが、このパディングを配置することで他のバグを隠している可能性があります。私の見解では、必要なスペースのみを割り当てます。クラッシュしたり、動作がおかしくなったりした場合は、マトリックスの実装でそれらを補うのではなく、その中の問題を修正してください。

于 2012-04-25T00:00:21.533 に答える