变量值正在发生变化

时间:2018-01-24 06:07:20

标签: c++

我有一个我正在测试的模板类:

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),那么问题就会消失,如果这有帮助的话。

2 个答案:

答案 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