简体   繁体   English

std :: vector中的内存泄漏代表2D数据

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

I have written a simple templated Matrix class to use with my main application which is manipulating data matricies. 我编写了一个简单的模板化Matrix类,用于操作数据基质的主应用程序。 The truncated Matrix code is: 截断的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];
}

As you can see I am just representing a 2D matrix as a vector and giving wrapper methods to hide that fact. 正如您所看到的,我只是将2D矩阵表示为向量,并提供包装方法来隐藏该事实。 Even though I resize the stack variable matrixRepresentation to 即使我将堆栈变量matrixRepresentation调整为

(r+1)(c+1)

I end up with memory corruption problems later in the code and valgrind tells me the following: 我最后在代码中遇到了内存损坏问题,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)

The readAllData() method (the user of this matrix class) is simply reading from a text file and trying to populate the matrix 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();
}

The header values are valid (eg theHeader.totalNumSamples = 15, theHeader.numFeatures = 100). 标头值有效(例如,theHeader.totalNumSamples = 15,theHeader.numFeatures = 100)。

Please let me know if I can provide any more information, I could really use some help with this. 如果我能提供更多信息,请告诉我,我真的可以使用一些帮助。

This snippet (which appears twice in your code): 此代码段(在代码中出现两次):

 [row + col*maxCols]

Isn't correct. 不对。 It should be [row * maxCols + col] or [col*maxRows + row] 它应该是[row * maxCols + col][col*maxRows + row]

And for that matter you don't need to allocate matrixRepresentation.resize((r+1)*(c+1)); 就此而言,您不需要分配matrixRepresentation.resize((r+1)*(c+1)); you can allocate instead matrixRepresentation.resize(r*c); 你可以改为分配matrixRepresentation.resize(r*c);

You should do the math on the extreme cases (like access to element (maxRows-1,maxCols-1) to check this yourself for understanding purposes). 您应该在极端情况下进行数学运算(例如访问元素(maxRows-1,maxCols-1)(maxRows-1,maxCols-1)检查以便理解)。

Does this solve your problem? 这会解决您的问题吗?

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

It might or might not solve it, but it is very much worth a try, if only to rule out trouble in the initialization of the Matrix . 它可能会或可能不会解决它,但它非常值得一试,如果只是为了排除Matrix初始化的麻烦。

Update: @ChrisA.'s answer is better. 更新:@ ChrisA。答案更好。 Try that first. 先尝试一下。

Not sure what Valgrind's specific issue is, but I found this: 不确定Valgrind的具体问题是什么,但我发现了这个:

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

In your constructor then you are creating, say, a 3x3 matrix but are allocating 16 places, not 9. While this shouldn't be a problem necessarily, you're likely hiding other bugs by having this padding in place. 在您的构造函数中,然后您创建一个3x3矩阵,但是分配16个位置,而不是9.虽然这不一定是一个问题,但您可能通过使用此填充来隐藏其他错误。 My take would be to only allocate the space you need, and if you find yourself crashing or otherwise behaving badly, fix the issues therein instead of compensating for them in your Matrix implementation. 我的看法是只分配你需要的空间,如果你发现自己崩溃或表现不好,请修复其中的问题,而不是在Matrix实现中补偿它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM