【问题标题】:c++ segfault in class vectorc++ 类向量中的段错误
【发布时间】:2018-11-18 03:57:41
【问题描述】:

我一直在玩用 C++ 制作游戏,只是为了练习编程。我创建了一个类,它本质上是一个 2d 单元格向量,用作地牢的不同图块。当我尝试调用我的函数将边缘单元格变成墙时,我得到一个段错误 11。根据我的研究,错误是试图访问超出向量范围的元素,或者我已经用完了堆内存但我不确定这里是否属于这种情况。

int main(){
    floor myfloor(18,9);
    myfloor.setwalls();
}

#ifndef FLOOR_H
#define FLOOR_H
#include "cell.h"
#include <vector>

using namespace std;
class floor{
public:
    floor(int xmax, int ymax);
     void setwalls();
private:
     int sizeX;
     int sizeY;
     vector< vector<cell*> > layout;
};
#endif

floor::floor(int xmax, int ymax){
    sizeX = xmax;
    sizeY = ymax;
    layout.resize(xmax, vector<cell*>(ymax));

    for(int i = 0; i < xmax; i++){
        for(int j = 0; j < ymax; j++){
            layout[i][j] = new cell();
        }
     }
}
void floor::setwalls(){
    for(int i = 0; i < sizeY; i++){
        layout[0][i]->setwall();
        layout[sizeX][i]->setwall();
    }
    for(int i = 0; i < sizeX; i++){
        layout[i][0]->setwall();
        layout[i][sizeY]->setwall();
 }
}

是什么导致了这里的 segfault 11?我所做的测试表明我的程序可以到达 setwalls() 但它似乎会在尝试访问布局向量的第一个元素时立即出现段错误。

【问题讨论】:

  • 越界访问或空指针取消引用。
  • layout[sizeX][i]layout[i][sizeY] 超出范围
  • 我建议您不要使用sizeXsizeY等无关变量来表示向量中的条目数。向量通过使用vector::size() 函数知道自己的大小——不需要通过使用不必要的变量来实现冗余。通过使用不必要的变量(例如 sizeXsizeY),如果向量碰巧改变了大小并且您没有更新 sizeXsizeY,那么您就有可能在代码中引入错误。
  • 另外,如果 floor 的第一个参数为 0,则所有其他函数都将失败,因为向量为空。

标签: c++ vector segmentation-fault


【解决方案1】:

你做错了一些事情,所以我给你写了一个关于如何使用多维向量的例子。

#include<vector>
   #include<iostream>

 using namespace std;

 int main()
 {
     vector < vector < int >>myarr;

     myarr.resize(100);         // resizes 1st dimension 
     for (auto i = 0; i < 100; i++)
    myarr[i].resize(100);   // resizes 2nd dimension

// initilization
for (int i = 0; i < 100; i++)
    {
    for (int j = 0; j < 100; j++)
        myarr[i][j] = j;    // 0- 99 100 times.
     }

     for (int i = 0; i < 100; i++)
     {
    for (int j = 0; j < 100; j++)
              cout << myarr[i][j] << " ";

        cout << endl;
     }
 }

您没有正确调整矢量的大小,并且没有正确初始化它以适应您的使用方式。此外,您的类型应该是 std::unique_ptr 并且您使用 std::make_unique 对其进行初始化,并且两者都存在于内存标头中。

你的代码应该是

 int main(){
     floor myfloor(18,9);
     myfloor.setwalls();
 }

 #ifndef FLOOR_H
#define FLOOR_H
#include "cell.h"
 #include <vector>
 #include<memory>

 using namespace std;
 class floor{
 public:
     floor(int xmax, int ymax);
      void setwalls();
 private:
      int sizeX;
      int sizeY;
      vector<vector<unique_ptr<cell*>>> layout;
 };
 #endif

 floor::floor(int xmax, int ymax){
     sizeX = xmax;
     sizeY = ymax;
     layout.resize(xmax);

     for(int i = 0; i < xmax; i++)
          layout[i].resize(ymax);

     for(int i = 0; i < xmax; i++){
         for(int j = 0; j < ymax; j++){
             layout[i][j] = make_unique(cell());
         }
      }
 }
 void floor::setwalls(){
     for(int i = 0; i < sizeY; i++){
         layout[0][i]->setwall();
         layout[sizeX - 1][i]->setwall();
     }
     for(int i = 0; i < sizeX; i++){
         layout[i][0]->setwall();
         layout[i][sizeY - 1]->setwall();
  }
 }

现在你的板子将是你想要的大小。

【讨论】:

    【解决方案2】:

    索引从 0 开始。因此,bounds 的有效值为 0

    您需要使用 sizeX-1 而不是 sizeX。 sizeY 也一样。

    【讨论】:

    • 他的第二个维度总是大小为 0。他从不调整任何第二维度的大小。
    • @johnathan,对于这个问题的范围,我的回答是完全有效的。如有疑问,请咨询ideone.com/44CxDX
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-01-16
    • 2019-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多