【问题标题】:invalid writes valgrind causing segmentation fault无效写入 valgrind 导致分段错误
【发布时间】:2020-08-12 22:39:10
【问题描述】:

我正在尝试创建一个迷宫类,它可以读取具有迷宫描述的输入流并返回一个迷宫。但是,当我使用这个给定的输入流运行测试时:

20 10
####################
#................<.#
#..................#
#...###............#
#.....#............#
#.....#............#
#...###............#
#..................#
#..................#
####################

它给出了一个分段错误,我在 valgrind 上运行目标文件来检查发生了什么:

Invalid write of size 8
==2482545==    at 0x4032CD: Maze::setTile(Position const&, Tile*) (maze.cpp:47)
==2482545==    by 0x40347B: Maze::read(std::istream&) (maze.cpp:67)
.....
==2482545==  Address 0x0 is not stack'd, malloc'd or (recently) free'd

我真的不明白为什么会出现分段错误或无效写入,在我的代码中,我应该在 setTile 函数中为每个图块分配空间,所以应该有空间供我编写。我还将 tile_collection 与我的构造函数堆叠在一起,因此当我调用 Maze(20,10) 时应该初始化 tile_collection,并且 setTile 内部的调整大小应该可以正常工作。你能指出我错过了什么吗?先感谢您。我知道我在 3 小时前问了一个非常相似的问题,但我仍然坚持这个无效的写入。(Position 类和 tilefactory 类是 2 个给定的文件,所以它们应该可以正常工作) 这是头文件中声明的类:


class Maze {
private:
  // TODO: add fields
  int Width;
  int Height;
  std::vector<Tile*> tile_collection;

这是我的 cpp 文件:

Maze::Maze(int width,int height):
  Width(width),Height(height){
  tile_collection[(width-1)*(height)];
}

}


void Maze::setTile(const Position &pos,Tile *tile){
  tile_collection[pos.getX()+pos.getY()*(Width)]=tile;
}


Maze *Maze::read(std::istream &in){
  int x;int y;char c;
  if ((in>>x)&&(in>>y)){
      Maze *new_maze=new Maze(x,y);
      //loop over the specified maze dimension
        for (int i=0;i<y;i++){
          for (int j=0;j<x;j++){
            if (in>>c){
              //using tilefactory to change character into a tile
              TileFactory *fac=TileFactory::getInstance();
              Tile* temp=fac->createFromChar(c);
              //if createFromChar fails, return nullptr, otherwise set tile at position j,i
              if (temp==nullptr){
                return nullptr;
              }
              else{
                new_maze->setTile(Position(j,i),temp);
              }
            }
          }
        }
        return new_maze;
  }
  else{
    return nullptr;
  }
}

【问题讨论】:

  • 嗨,我认为是这一行:tile_collection[pos.getX()+pos.getY()*(Width)]=tile;但我应该在构造函数中定义 tile_collection[(width-1)*(height)]

标签: c++ debugging vector segmentation-fault


【解决方案1】:

我怀疑你看到的错误是这行的结果:

          TileFactory *fac=fac->getInstance();

您正在声明一个名为 fac 的本地指针变量,但您正试图通过相同的指针变量调用方法 (getInstance()),而该指针变量甚至还没有被设置为任何值。对我来说似乎是灾难的秘诀!

【讨论】:

  • 嗯,我认为 TileFactory 类不允许构造函数,所以我只能获取它的一个实例
  • 如果是静态方法,正确的调用方式是TileFactory * fac = TileFactory::getInstance();
  • 谢谢,我已修复并重新编译它,但我仍然在这一行收到无效写入错误:tile_collection[pos.getX()+pos.getY()*(Width)]=tile;但我想知道,因为我在构造函数中声明了我的 tile_collection,所以这不应该是 null ptr;我真的很难找出问题出在哪里
  • 您可以检查它是否为 NULL 指针...在该行之前添加一个临时调试打印命令,例如fprintf(stderr, "DEBUG this=%p tile=%p\n", this, tile);,然后在它之前查看程序的输出崩溃以查看是否有任何打印的指针值是 0x0
  • 顺便说一句 tile_collection 不能为 NULL,因为它不是指针。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-04
  • 1970-01-01
  • 2011-02-06
  • 2015-09-11
  • 2013-11-13
  • 2012-02-25
相关资源
最近更新 更多