C ++向量值不断变化?

时间:2016-09-21 21:37:31

标签: c++ vector

这是一个非常简单的问题。我正在为一个练习写一个滑块益智游戏。

1, 1, 1, 1, 1,
1, 0, 3, 4, 1,
1, 0, 2, 2, 1,
1, 1, 1, 1, 1,

它接收上面表格中的输入,' 0'代表空格,' 1'代表墙壁,以及代表街区的所有其他数字。

以下是游戏状态的类定义和构造函数:

class GameState {

   public:
      GameState(int hght, int wdth);
      GameState(const GameState &obj);
      ~GameState();
      int getHeight();
      int getWidth();
      int getElem(int i, int j);
      void setElem(int i, int j, int val);
      void display();
      void readFile(char* filename);
      bool checkSolved();
      map<int, vector<int*> > blockLocations;
      vector<int> blockList;
      void getBlockLocations();
      void findBlock(int n);
   private:
      int **grid;
      int height, width;
      void allocate() {
         grid = new int*[height];
         for(int i = 0; i < height; i++)
         {
            grid[i] = new int[width];
         }
      }
};

GameState::GameState(int hght, int wdth) {
   height = hght;
   width = wdth;
   allocate();
   for(int i = 0; i < hght; i++) {
      for (int j = 0; j < wdth; j++) {
         grid[i][j] = 0;
      }
   }
};

基本上,网格由整数的二维指针数组表示。 heightwidth不言自明; blockLocations是将块编号映射到其形式(y,x)的逐点坐标的映射。目前,如果一个块占用多个空格,则仅列出最右边的空间。矩阵初始化为零,只有零;实际值从csv中读入。

所有这些方法都已定义,但关注的两种方法是getBlockLocations()findBlock(int n)

void GameState::getBlockLocations() {
   for (int i = 0; i < height; i++) {
      for (int j = 0; j < width; j++) {
         blockList.push_back(grid[i][j]);
         int pos[2] = {i, j};
         vector<int*> v;
         v.push_back(pos);
         blockLocations[grid[i][j]] = v;
      }
   }
}

void GameState::findBlock(int n) {
   vector<int>::iterator it;
   it = find(blockList.begin(), blockList.end(), n);
   if (it != blockList.end()) {
      vector<int*> * posList = &blockLocations[n];
      for (int itr = 0; itr < posList->size(); itr++) {
         vector<int*> curPos = *posList;
         cout << curPos[itr][0] << ", " << curPos[itr][1] << endl;
      }
   }
}

当我实际运行此问题时,问题出现了。作为一个案例,当我运行getBlockLocations()时,它会正确存储&#39; 2&#39;如(2,3)。但是,当我要求程序用findBlock(2)显示该块的位置时,结果输出是(16515320,0)。它每次都不同但永远不会纠正。我没有看到指针错误,我正在制作这样的错误值。

1 个答案:

答案 0 :(得分:2)

那很糟糕:

 for (int j = 0; j < width; j++) {
     blockList.push_back(grid[i][j]);
     int pos[2] = {i, j};
     vector<int*> v;
     v.push_back(pos);
     blockLocations[grid[i][j]] = v;
  }

您在本地创建pos变量并存储其引用。当你超出for循环的范围时,它是无效的/数据可以被其他东西替换。

(实际上正如Barmar指出的那样,因为pos地址在循环中总是相同的,所以每次迭代时值都会改变)

您可以使用std::pair<int,int>来存储您的值。 当您在向量中插入对时,数据将被复制,而不仅仅是指针:它是安全的。

typedef std::pair<int,int> IntIntPair;

IntIntPair pos(i,j);
std::vector<IntIntPair> v;