0

そこで、Piece 型のオブジェクトへのポインタの 2 次元配列を作成しようとしています。問題は、ポインターを配列に割り当てようとすると、セグメンテーション違反が発生することです。割り当てを開始する前に、いつか配列を初期化する必要があることに気付きましたが、正しく取得できません。

これは、ポインターの 2 次元配列を含む Map のヘッダー ファイルです。

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

       }
     }
  }
}

name は、特定のマップをロードするための情報を含むファイルの名前を保持する文字列です。

また、関数 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;
  }
}

Waypoint は Piece の派生クラスです。

4

2 に答える 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]これは、everyに割り当てられたオブジェクトnewまたは NULLのいずれかが含まれていることを前提としており、両方で機能します。あなたのコードを見ると、それはあなたのケースのようです。ただし、そのうちの1つが割り当てられていない場合は機能しません(あなたのケースではありません)。

于 2013-10-06T14:39:06.940 に答える
0

std::vector<std::vector<Pieces>>車輪を再発明する (機能しないため、しようとしている) 代わりに使用します。安全で簡単で、手作業によるメモリ管理の頭痛の種を避けることができます。

于 2013-10-06T14:47:14.927 に答える