【发布时间】:2020-04-28 20:09:48
【问题描述】:
我正在尝试创建一个迷宫类,它可以读取具有迷宫描述的输入流并返回一个迷宫。但是,当我使用这个给定的输入流运行测试时:
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 内部的调整大小应该可以正常工作。你能指出我错过了什么吗?提前谢谢你。
Maze::Maze(int width,int height):
Width(width),Height(height){
vector<Tile*>* tile_collection=new vector<Tile*>;
}
void Maze::setTile(const Position &pos,Tile *tile){
tile_collection.resize(pos.getX()+pos.getY()*Width);
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=fac->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;
}
}
【问题讨论】:
-
vector<Tile*>* tile_collection=new vector<Tile*>;正在分配给局部变量,而不是成员变量。您可以将tile_collection=new vector<Tile*>;分配给成员,但最好的办法是消除指针并将vector<Tile*> tile_collection定义为成员变量。保存指针和动态分配以备不时之需,而对于像std::vector这样的库容器,这几乎是不可能的。他们的工作是为您处理内存管理。 -
更深入地看,
tile_collection.resize(pos.getX()+pos.getY()*Width);中.符号的使用表明成员tile_collection不是指针,因此问题与我上面描述的不同。上面的内容仍然是错误的,这是内存泄漏,但可能与您正在寻找的错误无关。 -
感谢您的帮助!嗯,所以我只需要在我的头文件中定义 vector
tile_collection 而不必初始化它?在我的 getTile 中调整大小的所有操作仍然有效吗? -
vector照顾自己。如果您有足够的信息在构造函数中调整它的大小,并且使用width和height,您可以Maze::Maze(int width,int height): Width(width),Height(height), tile_collection(width * height)并省去自己以后必须resize它。
标签: c++ class debugging segmentation-fault valgrind