我编写了一个简单的模板化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的大小调整为</ p>
(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)。
如果我能提供更多信息,请告诉我,我真的可以使用这方面的帮助。
答案 0 :(得分:8)
此代码段(代码中出现两次):
[row + col*maxCols]
不正确。它应为[row * maxCols + col]
或[col*maxRows + row]
就此而言,您无需分配matrixRepresentation.resize((r+1)*(c+1));
,而是可以分配matrixRepresentation.resize(r*c);
你应该对极端情况进行数学运算(比如访问元素(maxRows-1,maxCols-1)
以自行检查以便理解)。
答案 1 :(得分:1)
这会解决您的问题吗?
template <typename T>
Matrix<T>::Matrix(const int r, const int c) :
maxRows(r),
maxCols(c),
matrixRepresentation((r+1)*(c+1))
{}
它可能会或可能不会解决它,但它非常值得一试,如果只是为了排除Matrix
的初始化中的麻烦。
更新:@ ChrisA。答案更好。先尝试一下。
答案 2 :(得分:1)
不确定Valgrind的具体问题是什么,但我发现了这个:
maxRows = r;
maxCols = c;
matrixRepresentation.resize((r+1)*(c+1));
在你的构造函数中,你创建了一个3x3矩阵,但是分配了16个位置,而不是9个。虽然这不一定是一个问题,但你可能通过填充这个填充来隐藏其他错误。我的看法是只分配你需要的空间,如果你发现自己崩溃或表现不好,请修复其中的问题,而不是在Matrix实现中补偿它们。