簡體   English   中英

std :: vector中的內存泄漏代表2D數據

[英]memory leak in std::vector representing 2D data

我編寫了一個簡單的模板化Matrix類,用於操作數據基質的主應用程序。 截斷的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)。

如果我能提供更多信息,請告訴我,我真的可以使用一些幫助。

此代碼段(在代碼中出現兩次):

 [row + col*maxCols]

不對。 它應該是[row * maxCols + col][col*maxRows + row]

就此而言,您不需要分配matrixRepresentation.resize((r+1)*(c+1)); 你可以改為分配matrixRepresentation.resize(r*c);

您應該在極端情況下進行數學運算(例如訪問元素(maxRows-1,maxCols-1)(maxRows-1,maxCols-1)檢查以便理解)。

這會解決您的問題嗎?

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

它可能會或可能不會解決它,但它非常值得一試,如果只是為了排除Matrix初始化的麻煩。

更新:@ ChrisA。答案更好。 先嘗試一下。

不確定Valgrind的具體問題是什么,但我發現了這個:

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

在您的構造函數中,然后您創建一個3x3矩陣,但是分配16個位置,而不是9.雖然這不一定是一個問題,但您可能通過使用此填充來隱藏其他錯誤。 我的看法是只分配你需要的空間,如果你發現自己崩潰或表現不好,請修復其中的問題,而不是在Matrix實現中補償它們。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM