在C ++中破坏指向动态二维数组的指针

时间:2012-11-17 23:29:20

标签: c++ multidimensional-array

作为我从学校获得的作业的一部分,我一直在努力解决这个分配/破坏问题很长一段时间,基本上我需要分配一个我设计的简单类的2d数组指针。

class RobotsWorld{
public:
    RobotsWorld(int width,int hight);
    ~RobotsWorld();
    /**
     * copy,Assign,operator=
     */
    //RobotsWorld(const RobotsWorld &);
    //void Assign(const RobotsWorld &);
    //RobotsWorld& operator=(const RobotsWorld &);


    bool addRobot(Robot & r,Point p);
    bool moveRobot(Robot & r);
    bool removeRobot(Robot & r);
    Point getPosition(Robot r);
    string toString();

    Robot* getRobotInWorld(Robot & r);

    /** validation functions **/
    bool checkOutOfBounds(int,int);
    bool isEmptySlot(int x,int y);
    bool ableToMove(Robot &);




private:
    Robot*** robots;
    Point point;
    int width,height;
};

这不是函数的完整源文件,但这些函数会导致崩溃\内存丢失。 (是的,它必须被定义为三重指针 - ***机器人)

RobotsWorld::RobotsWorld(int width,int height)
:width(width),height(height)
{
    robots = new Robot**;
    *robots = new Robot*[height];

    for(int i = 0 ; i < height ; i++){
        robots[i] = new Robot*[width];
        for(int j = 0 ; j < width ; j++)
            robots[i][j] = NULL;
    }

}

RobotsWorld::~RobotsWorld(){

    for(int i = 0 ; i < height ; i++){
        delete [] robots[i];
        robots[i] = NULL;
    }
    delete [] *robots;
    delete **robots;
}

机器人类和主要没有分配什么呢。 我一直试图寻找一个解决方案,但即使描述这种情况也证明这很困难。

6 个答案:

答案 0 :(得分:4)

您需要两个嵌套循环来删除2D指针数组 - 删除单个机器人,以及删除机器人行:

RobotsWorld::~RobotsWorld(){
    for(int i = 0 ; i < height ; i++) {
        for(int j = 0 ; j < width ; j++) {
            delete robots[i][j]; // Delete each individual robot
        }
        delete[] robots[i]; // Delete the row of robots
    }
    // Finally delete the 2D array itself
    delete[] robots;
}

虽然删除后设置指针NULL通常是个好主意,但在析构函数中这样做会浪费CPU周期;我建议跳过是。

这是很多工作(因为我确定你可以看到)。使用标准C ++库可以通过使用合适的容器(例如,

)来帮助您避免所有这些工作
vector<vector<unique_ptr<Robot> > > robots;

现在,与管理机器人内存相关的任务将自动处理。

答案 1 :(得分:1)

最后一行:

delete **robots;

很可能是你的问题。它应该是:

delete robots;

答案 2 :(得分:1)

robots = new Robot**;
*robots = new Robot*[height];

不正确,你想要

robots = new Robot**[height];

答案 3 :(得分:0)

我无法想象为什么有一个T***并且我当然无法在没有辅助类的情况下为这样的事情维护资源!如果我不能使用std::vector<T>来帮助维护我应该实现一个类似的类(好吧,对我来说很简单:无论如何我已经实现了我自己的C ++标准库版本......)。

我没有找到所有问题,但直接的问题是你new robots**并将结果视为robots[i]中的元素以上。

答案 4 :(得分:0)

我在这个答案中复制了我的评论:

您也可以使用:

template <int WIDTH, int HEIGHT> 
class RobotsWorld
{
  public:
     /*... functions ...*/

  private:
     Robot robots[WIDTH][HEIGHT];
     /*... other private data ...*/
 };

你不必关心new / delete东西;-)

但是你必须实现一些operator来允许:

RobotsWorld<3,4> rw34; 
RobotsWorld<5,6> rw56 = rw34;
if (rw56 == rw34) /*...*/;

如果您不需要允许上述行操作,那么template是一个优雅的解决方案。

答案 5 :(得分:0)

您想要存储一个指向Robot的2维指针数组。这是一个可能的初始化例程:

RobotsWorld::RobotsWorld(int width,int height)
:width(width),height(height)
{
  robots = new (Robot**)[height];

  for(int i = 0 ; i < height ; i++){
      (*robots)[i] = new (Robot*)[width];
      for(int j = 0 ; j < width ; j++)
          robots[i][j] = NULL;
  }
}

析构函数应该实现双重操作。