2013-10-06 4 views
0

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

Вот файл заголовка Карты, который содержит 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); 
    } 

     } 
    } 
    } 
} 

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

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

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; 
    } 
} 

Точку является производным классом шт.

+0

Я предполагаю, что размер массива неизвестен во время компиляции? Есть ли ограничение на размер массива? – rdans

+1

вы отбрасываете «куски» перед тем, как выделить его, даже если это указатели, вам нужно выделить указатели. еще лучше, используйте std: vector вместо этого, чтобы отслеживать, что и когда удалять ваши указатели, например. 'vector > pieces;' –

+0

'pieces [i] [j] = pieceType (строка [j]); это не распределение памяти, это назначение значения. – ipinak

ответ

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>> вместо (пытается, потому что он не работает) изобретает колесо. Это безопасно, легко и позволяет избежать головных болей от ручного управления памятью.

Смежные вопросы