我有一个我正在测试的模板类:
class SparseMat {
private:
FHvector<FHlist<MatNode<Object>>> matrix;
int numOfRows, numOfCols;
const Object defaultValue;
public:
SparseMat(int r, int c, const Object& defaultVal);
const Object & get(int r, int c) const;
bool set(int r, int c, const Object& x);
};
template <class Object>
SparseMat<Object>::SparseMat(int r, int c, const Object& defaultVal) : defaultValue(defaultVal) {
numOfRows = r;
numOfCols = c;
matrix.resize(numOfRows);
for (int counter = 0; counter < numOfRows; counter++) {
FHlist<MatNode<Object>> currentRow;
matrix.push_back(currentRow);
}
}
template <class Object>
bool SparseMat<Object>::set(int r, int c, const Object& x) {
if (r >= numOfRows || r < 0 || c < 0 || c >= numOfCols) {
return false;
}
if (r == 9 && c == 9) {
cout << x << endl;
}
if (r == 9 && c == 9) {
cout << x << endl;
}
for (FHlist<MatNode<Object>>::iterator iter = matrix[r].begin(); iter != matrix[r].end(); ++iter) {
if ((*iter).getCol() == c) {
if (x == defaultValue) {
matrix[r].erase(iter);
return true;
}
else {
(*iter).data = x;
return true;
}
}
}
matrix[r].push_back(MatNode<Object>(c, x));
return true;
}
template <class Object>
const Object & SparseMat<Object>::get(int r, int c) const {
if (r >= numOfRows || r < 0 || c < 0 || c >= numOfCols) {
throw OutOfBoundsException();
}
FHlist<MatNode<Object>> wantedRow = matrix[r];
for (FHlist<MatNode<Object>>::iterator iter = wantedRow.begin(); iter != wantedRow.end(); ++iter) {
if ((*iter).getCol() == c) {
return (*iter).getData();
}
}
return NULL;
}
MatNode如下:
template <class Object>
class MatNode
{
protected:
int col;
public:
Object data;
MatNode(int cl = 0, Object dt = Object()) : col(cl), data(dt) { }
int getCol() const { return col; }
const Object & getData() const {return data; }
};
非常奇怪的是我的两个输出打印了两个不同的东西。如预期的那样,第一次打印21。第二个打印出一些随机浮动,这绝对不是预期的,因为我在两个输出之间没有改变x。
#include <iostream>
using namespace std;
#include "FHsparseMat.h"
#define MAT_SIZE 100000
typedef SparseMat<float> SpMat;
int main()
{
SpMat mat(MAT_SIZE, MAT_SIZE, 0);
mat.set(3, 9, 21);
cout << mat.get(3, 9) << endl;
mat.set(9, 9, 21);
cout << mat.get(9, 9) << endl;
mat.set(9, 9, mat.get(3,9));
cout << mat.get(9, 9) << endl;
}
这是我的测试员。如果我用硬编码值21替换mat.get(3,9),那么问题就会消失,如果这有帮助的话。
答案 0 :(得分:1)
get()
的返回类型为const Object &
。
结果,函数的最后一行
return 0; // source code says NULL but preprocessor replaces that with 0
返回对使用值0
隐式构造的临时Object的悬空引用。
当然,使用该悬挂引用会导致未定义的行为。
目前还不完全清楚为什么会到达那条线,但是如果你把相同的值写到同一个位置,擦除一个项目的逻辑肯定是可疑的。 IMO只应在写入的值为零时删除项目。
答案 1 :(得分:0)
问题是Object MatNode::getData() const
没有返回引用,而您正在const Object & SparseMat<Object>::get(int r, int c) const
中返回引用。将其更改为:
Object SparseMat<Object>::get(int r, int c) const
。