C++ vector 值不断变化?

标签 c++ vector

这是一个真正简单的问题。我正在为练习编写一个 slider 益智游戏。

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

它按照上面的形式接收输入,“0”代表空白,“1”代表墙,所有其他数字代表方 block 。

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

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 是一个映射,它将 block 编号映射到其形式为 (y, x) 的逐点坐标。目前,如果一个 block 占用多个空间,则只列出最右下角的空间。矩阵初始化为零;实际值是从 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() 时,它正确地将“2”的坐标存储为 (2, 3)。但是,当我要求程序使用 findBlock(2) 显示该 block 的位置时,结果输出类似于 (16515320, 0)。每次都不一样,但永远不正确。我没有看到我为了得到这样的错误值而犯的指针错误。

最佳答案

这很糟糕:

 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>而是存储您的值。 当您将对插入 vector 时,数据会被复制,而不仅仅是指针:它是安全的。

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

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

关于C++ vector 值不断变化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39626973/

相关文章:

java - 为什么我的旋转矩阵不起作用?

c++ - 是否可以将基类 is struct 分配给派生类 struct

c++ - 使用 Boost.TR1 替换 native VS 2010 (VC10) tr1 库

python - 如何在 python 中为每一对分开做矩阵向量内积?

r - 在R中,如果矩阵按行选择第一个元素,如果向量选择第一个元素

vector - 关于 Julia 中向量的行为/向量的行为

c++ - 保存/序列化 boost 或 std 正则表达式

c++ - STL vector 性能

c++ - 我可以使用 declval 来构造一个未使用的返回值吗?

Java - 深度克隆具有多种类型元素的 Vector