无法为2维指针数组c ++分配内存

时间:2021-09-27 21:18:32

So I'm trying to create a 2 dimensional array of pointers to a object of type Piece. The problem is when i try assign a pointer to a piece to the array i get a segmentation fault. I realized I needed to initialize to array to sometime before I can start allocating but I can't get it right.

所以我试图创建一个指向Piece类型对象的二维数组指针。问题是当我尝试将一个指针分配给数组时,我得到一个分段错误。我意识到我需要在我开始分配之前的某个时候初始化到数组,但是我无法做到正确。

Here is the header file of Map which contains a 2-d array of pointers.

这是Map的头文件,它包含一个2-d指针数组。

#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

The array I'm talking about is pieces.

我正在谈论的阵列是碎片。

I try to allocate this in the constructor of Map.

我尝试在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);
     }

       }
     }
  }
}

Where name is a string that holds the name of the file that has the information for loading a particular map.

其中name是一个字符串,其中包含具有用于加载特定映射的信息的文件的名称。

Also the function pieceType is as follows:

函数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 is a derived class of Piece.

Waypoint是Piece的派生类。

2 个解决方案

#1


2  

The problem is indeed that you have to initialize that array. Like this:

问题确实是你必须初始化那个数组。像这样:

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

Write that just after you get width and height, and before you start using pieces. But something you should know: for each new, there should be a corresponding delete, or else that memory will never be freed, and you will get a memory leak. To free that memory, add this in your destructor:

在获得宽度和高度之后,在开始使用碎片之前写下。但是你应该知道的事情:对于每个新的,应该有一个相应的删除,否则永远不会释放内存,你将得到内存泄漏。要释放该内存,请在析构函数中添加:

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

This assumes that every pieces[i][j] contains either an object allocated with new or NULL, and it works with both. Looking at your code, that seems to be your case. However, it would not work if one of them is not assigned (not your case).

这假设每个piece [i] [j]包含一个用new或NULL分配的对象,并且它可以同时使用。看看你的代码,这似乎是你的情况。但是,如果没有分配其中一个(不是你的情况),它将无法工作。

#2


0  

Use std::vector<std::vector<Pieces>>instead of (trying to, because it does not work) reinventing the wheel. Its safe, easy, and avoids getting manual-memory-management headaches.

使用std :: vector >代替(尝试,因为它不起作用)重新发明*。它安全,简单,避免了手动内存管理的麻烦。

#1


2  

The problem is indeed that you have to initialize that array. Like this:

问题确实是你必须初始化那个数组。像这样:

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

Write that just after you get width and height, and before you start using pieces. But something you should know: for each new, there should be a corresponding delete, or else that memory will never be freed, and you will get a memory leak. To free that memory, add this in your destructor:

在获得宽度和高度之后,在开始使用碎片之前写下。但是你应该知道的事情:对于每个新的,应该有一个相应的删除,否则永远不会释放内存,你将得到内存泄漏。要释放该内存,请在析构函数中添加:

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

This assumes that every pieces[i][j] contains either an object allocated with new or NULL, and it works with both. Looking at your code, that seems to be your case. However, it would not work if one of them is not assigned (not your case).

这假设每个piece [i] [j]包含一个用new或NULL分配的对象,并且它可以同时使用。看看你的代码,这似乎是你的情况。但是,如果没有分配其中一个(不是你的情况),它将无法工作。

#2


0  

Use std::vector<std::vector<Pieces>>instead of (trying to, because it does not work) reinventing the wheel. Its safe, easy, and avoids getting manual-memory-management headaches.

使用std :: vector >代替(尝试,因为它不起作用)重新发明*。它安全,简单,避免了手动内存管理的麻烦。