C ++ Segfault в классе вектор - PullRequest
0 голосов
/ 18 ноября 2018

Я занимался созданием игры на с ++ только для практики программирования. Я создал класс, который по сути является двумерным вектором клеток, которые функционируют как различные тайлы подземелья. Когда я пытаюсь вызвать мою функцию для превращения краевых ячеек в стены, я получаю сегмент-ошибку 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 (), но, похоже, у нее возникает ошибка по умолчанию, как только она пытается получить доступ к первому элементу вектора макета.

Ответы [ 2 ]

0 голосов
/ 18 ноября 2018

вы делаете неправильно несколько вещей, поэтому я написал вам пример использования многомерных векторов.

#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();
  }
 }

теперь ваша доска будет иметь размер в обоих измерениях, который вы хотите.

0 голосов
/ 18 ноября 2018

Индексы основаны на 0. Итак, допустимыми значениями границ являются 0 <= bound <= (N-1). </p>

Вам нужно использовать sizeX-1 вместо sizeX. То же самое для размера Y.

...