1

学校から受け取った課題の一部として、この割り当て/破棄の問題をかなりの時間解決しようとしてきました。基本的に、設計した単純なクラスの 2 次元配列ポインターを割り当てる必要があります。

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

ロボットクラスとメインは割り当てられませんでした。私は解決策を探していましたが、この状況を説明することさえ困難であることがわかりました.

4

6 に答える 6

4

ポインターの 2D 配列を削除するには、ネストされた 2 つのループが必要です。つまり、個々のロボットを削除し、ロボットの行を削除します。

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;

これで、ロボットのメモリ管理に関連するタスクが自動的に処理されます。

于 2012-11-17T23:34:20.313 に答える
1
robots = new Robot**;
*robots = new Robot*[height];

は間違っています。

robots = new Robot**[height];
于 2012-11-17T23:37:30.080 に答える
1

最後の行:

delete **robots;

おそらくあなたの問題です。そのはず:

delete robots;
于 2012-11-17T23:34:41.603 に答える
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;
  }
}

デストラクタは、デュアル操作を実装する必要があります。

于 2012-11-17T23:56:47.870 に答える
0

ヘルパー クラスがなけれT***ば、このようなリソースを維持することはできません。メンテナンスを手伝うことができない場合はstd::vector<T>、同様のクラスを実装します (まあ、私にとっては簡単です。とにかく、C++ 標準ライブラリの独自のバージョンを実装しました...)。

すべての問題を調べたわけではありませんが、当面の問題はnew robots**、結果を に複数の要素があるものとして扱うことですrobots[i]

于 2012-11-17T23:40:01.280 に答える
0

この回答のコメントをコピーします。

以下も使用できます。

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

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

そして、あなたは気にする必要はありませんnew/ delete;-)

operatorただし、許可するにはいくつかの s を実装する必要があります。

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

上記の行のような操作を許可する必要がない場合templateは、エレガントなソリューションです。

于 2012-11-17T23:43:56.497 に答える