c++ 类向量中的段错误

Posted

技术标签:

【中文标题】c++ 类向量中的段错误【英文标题】:c++ segfault in class vector 【发布时间】: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,则所有其他函数都将失败,因为向量为空。 【参考方案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

以上是关于c++ 类向量中的段错误的主要内容,如果未能解决你的问题,请参考以下文章

带有向量向量的段错误

声明向量类型变量的段错误<shared_ptr<int>>

调试难以捉摸的段错误

使用 vector<vector<int> > 成员实例化对象时的段错误

JNI_CreateJavaVM 上的段错误

glGenFramebuffers 中的段错误