简体   繁体   中英

destructing a pointer to a dynamic 2d array in C++

Iv'e been trying to solve this allocation/destruction problem for a significant amount of time as part of an assignment I got from school, basically I need to allocate a 2d array pointer of a simple class i designed.

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

this is not the full source file of the functions but these functions causes the crash\\memory loss. (and yes it has to be defined as a triple pointer - ***robots)

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

the robot class and the main got no allocation whats so ever. ive been trying to search for a solution but even describing this situation proved it self difficult.

You need two nested loops to delete a 2D array of pointers - to delete individual robots, and to delete rows of robots:

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

Although it is normally a good idea to set a pointer to NULL after deletion, doing so in the destructor is a waste of CPU cycles; I recommend skipping is.

This is a lot of work (as I'm sure you can see). Using the standard C++ library can help you avoid all this work by using a suitable container - say,

vector<vector<unique_ptr<Robot> > > robots;

Now the tasks related to managing the memory for your robots will be taken care automatically.

the last line:

delete **robots;

is most likely your problem. It should be:

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

is incorrect, you want

robots = new Robot**[height];

I cannot imagine why it would ever be necessary to have a T*** and Im certainly not able to maintain resources for something like this without helper classes! If I can't use std::vector<T> to help with the maintenance I wiould implement a similar class (well, it is easy for me: I have implemented my own version of the C++ standard library anyway...).

I haven't looked for all problems but the immediate oroblem is that you new robots** and treat the result as having more than element in robots[i] .

I copy my comment in this answer:

You can also use:

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

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

And you do not have to care about new / delete stuff ;-)

However you have to implement some operator s to allow:

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

If you do not need to allow operations as the lines above, then template is an elegant solution.

You want to store a 2 dimension array of pointers to Robot. Here's a possible initialization routine:

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

The destructor should implement the dual operation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM