C++ grid class (std::vector of cells) 自定义调整大小函数导致分段错误
C++ grid class (std::vector of cells) custom resizing function causes segmentation fault
我有一个由单元格组成的二维网格 class,我必须将单元格存储在模拟二维网格的一维 std::vector
(由于规范)中。
我编写了一个 Grid::resize
函数,可以将网格的大小调整为新的宽度和高度,但将网格的内容保留在保留区域内(所有新单元格都设置为
Cell::DEAD
).
我写了一个调整大小的函数,当 运行 导致分段错误时:11,我认为这意味着该函数正在尝试访问向量边界之外的数据,但我不确定错误在哪里是。
Class
class Grid {
private:
std::vector<Cell> grid_cells;
unsigned int width;
unsigned int height;
public:
Grid(const unsigned int width, const unsigned int height);
}
构造函数代码
Grid::Grid(const unsigned int width, const unsigned int height) {
std::vector<Cell> cells(width*height);
int i;
for(i=0;i<(width*height);i++){
cells[i] = Cell::DEAD;
}
this->width = width;
this->height = height;
this->grid_cells = cells;
}
调整大小功能
void Grid::resize(const unsigned int new_width, const unsigned int new_height) {
std::vector<Cell> new_cells(new_width*new_height);
unsigned int x, y;
for(x = 0; x < new_width; x++) {
for(y = 0; y < new_height; y++) {
if(x < this->width && y < this->height) {
new_cells[get_index(x,y)] = this->grid_cells[get_index(x,y)];
}
else {
new_cells[get_index(x,y)] = Cell::DEAD;
}
}
}
this->width = new_width;
this->height = new_height;
this->grid_cells = new_cells;
}
我的代码正在由 运行 上面的预制测试套件进行测试,我相信错误来自 for 循环的主体,因为当我将其注释掉时,测试套件 运行s 到最后,但是当它离开时我得到一个分段错误并且它停止 运行ning.
编辑:
get_index
将二维x,y坐标转换为一维索引的函数:
const unsigned int Grid::get_index(const unsigned int x, const unsigned int y) const{
return ((y * this->width) + x + 1);
}
const unsigned int
Grid::get_index(const unsigned int x, const unsigned int y) const{
return ((y * this->width) + x + 1);
}
您正在使用原始网格宽度来计算新网格中的索引。它们可能有很大的不同,因此您将复制错误的单元格或访问超出 new_cells
范围的内存
此外,实际上,当您尝试访问坐标为 (width-1, height-1)
的最后一个单元格(位于 height*width - width + width -1 + 1 = height*width
时,您总是会执行无效的内存访问。向量的最后一个有效索引是 height*width-1
您可以使用免费功能
unsigned int
get_index(const unsigned int x, const unsigned int y, const unsigned int width) const{
return (y * width) + x ;
}
并且有
new_cells[get_index(x,y, new_width)] = this->grid_cells[get_index(x,y, this->width)]
我有一个由单元格组成的二维网格 class,我必须将单元格存储在模拟二维网格的一维 std::vector
(由于规范)中。
我编写了一个 Grid::resize
函数,可以将网格的大小调整为新的宽度和高度,但将网格的内容保留在保留区域内(所有新单元格都设置为
Cell::DEAD
).
我写了一个调整大小的函数,当 运行 导致分段错误时:11,我认为这意味着该函数正在尝试访问向量边界之外的数据,但我不确定错误在哪里是。
Class
class Grid {
private:
std::vector<Cell> grid_cells;
unsigned int width;
unsigned int height;
public:
Grid(const unsigned int width, const unsigned int height);
}
构造函数代码
Grid::Grid(const unsigned int width, const unsigned int height) {
std::vector<Cell> cells(width*height);
int i;
for(i=0;i<(width*height);i++){
cells[i] = Cell::DEAD;
}
this->width = width;
this->height = height;
this->grid_cells = cells;
}
调整大小功能
void Grid::resize(const unsigned int new_width, const unsigned int new_height) {
std::vector<Cell> new_cells(new_width*new_height);
unsigned int x, y;
for(x = 0; x < new_width; x++) {
for(y = 0; y < new_height; y++) {
if(x < this->width && y < this->height) {
new_cells[get_index(x,y)] = this->grid_cells[get_index(x,y)];
}
else {
new_cells[get_index(x,y)] = Cell::DEAD;
}
}
}
this->width = new_width;
this->height = new_height;
this->grid_cells = new_cells;
}
我的代码正在由 运行 上面的预制测试套件进行测试,我相信错误来自 for 循环的主体,因为当我将其注释掉时,测试套件 运行s 到最后,但是当它离开时我得到一个分段错误并且它停止 运行ning.
编辑:
get_index
将二维x,y坐标转换为一维索引的函数:
const unsigned int Grid::get_index(const unsigned int x, const unsigned int y) const{
return ((y * this->width) + x + 1);
}
const unsigned int
Grid::get_index(const unsigned int x, const unsigned int y) const{
return ((y * this->width) + x + 1);
}
您正在使用原始网格宽度来计算新网格中的索引。它们可能有很大的不同,因此您将复制错误的单元格或访问超出 new_cells
此外,实际上,当您尝试访问坐标为 (width-1, height-1)
的最后一个单元格(位于 height*width - width + width -1 + 1 = height*width
时,您总是会执行无效的内存访问。向量的最后一个有效索引是 height*width-1
您可以使用免费功能
unsigned int
get_index(const unsigned int x, const unsigned int y, const unsigned int width) const{
return (y * width) + x ;
}
并且有
new_cells[get_index(x,y, new_width)] = this->grid_cells[get_index(x,y, this->width)]