Невозможно выделить память для двумерного массива указателей c ++

0

Поэтому я пытаюсь создать 2-мерный массив указателей на объект типа Piece. Проблема в том, что когда я пытаюсь назначить указатель на кусок массиву, я получаю ошибку сегментации. Я понял, что мне нужно инициализировать массив до того, как я начну выделять, но я не могу понять это правильно.

Вот файл заголовка карты, который содержит 2-мерный массив указателей.

#ifndef MAP_H
 #define MAP_H

 #include <iostream>
 #include <vector>
 #include <fstream>
 #include <stdio.h>
 #include <stdlib.h>
 #include <sstream>
 #include <string>
 #include <cstring>
 #include "Player.h"
 #include "Sprite.h"
 #include "Piece.h"
 #include "Messages.h"
 #include "PieceType.h" 

using namespace std;

class Map
{
    private:

        Piece*** pieces;
        int startingX;
        int startingY;
        int width;
        int height;
        string mapName;

    public:

        Map(string);
        ~Map();

        void printMap() const;
        Piece* pieceType(char);
        void setSprite(Piece*);
        void firstMove();
        void resetMap(string);

        bool moveUp(int, int);
        bool moveDown(int, int);
        bool moveLeft(int, int);
        bool moveRight(int, int);

        int getHeight();
        int getWidth();


};

#endif

Массив, о котором я говорю, это кусочки.

Я пытаюсь выделить это в конструкторе карты.

Map::Map(string name)
{
  ifstream map;
  string line;
  string dimention;
  mapName = name;

  map.open(name.c_str());

  if (map.good())
  {
    getline (map, line);

    int i = 0;

    while(line[i] != 'X')
    {
      dimention[i] = line[i];
      i++;
    }

    stringstream convert(dimention);

    convert >> width;

    int temp = i;
    dimention = "";
    i = 1;

    while(line[(i + temp)] != '\0')
    {
      dimention[i] = line[(i + temp)];
      i++;
    }

    stringstream convertTwo(dimention);

    convertTwo >> height;

    for (int i = 0; i < height; i++)
     {
       if (!(map.eof()))
       { 
     getline (map, line);
       }
       else
       {
     cout << "Error with file" << endl;
     break;
       }

       for (int j = 0; j < width; j++)
       {
     pieces[i][j] = pieceType(line[j]); //This is where I'm getting the segmentation fault

     cout << "assigned" << endl;

     if ((pieces[i][j])->getType() == WAYPOINT)
     {

       if (pieces[i][j]->getWaypointType() == 0)
       {
         startingX = j;
         startingY = i;
       }
     }

     else
     {       
     (pieces[i][j])->setXCordinate(j);
     (pieces[i][j])->setYCordinate(i);
     }

       }
     }
  }
}

Где имя - это строка, в которой содержится имя файла, который имеет информацию для загрузки определенной карты.

Также функция themeType выглядит следующим образом:

Piece* Map::pieceType(char type)
{
  Piece* temp;

  if (type == '.')
  {
    return NULL;
  }
  if (type == 'S')
  {
    temp = new Waypoint(0);
    return temp;
  }
  if (type == 'E')
  {
    temp = new Waypoint(1);
    return temp;
  }
}

Waypoint - производный класс Piece.

Теги:
arrays
pointers

2 ответа

2

Проблема в том, что вы должны инициализировать этот массив. Как это:

pieces=new Piece**[height];
for(int i=0;i<height;i++){
     pieces[i]=new Piece*[width];
}

Напишите это сразу после того, как вы получите width и height, и прежде чем начинать использовать pieces. Но что-то, что вы должны знать: для каждого new должно быть соответствующее delete, иначе эта память никогда не будет освобождена, и вы получите утечку памяти. Чтобы освободить эту память, добавьте это в свой деструктор:

for(int i=0;i<height;i++){
    for (int j = 0; j < width; j++){
        delete pieces[i][j];
    }
    delete[] pieces[i];
}
delete[] pieces;

Это предполагает, что каждая часть pieces[i][j] содержит либо объект, выделенный new либо NULL, и он работает с обоими. Глядя на ваш код, это кажется вашим делом. Однако это не сработает, если один из них не назначен (не ваше дело).

0

Используйте std::vector<std::vector<Pieces>> вместо (пытается, потому что он не работает) изобретает колесо. Это безопасно, легко и позволяет избежать головных болей от ручного управления памятью.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню