2

C ++で2D配列を返す必要があるかどうかを調べてみましたが、答えはまちまちでした。

一部の回答は、データが関数に対してローカルであり、データが返されるときに、配列が「ジャンクデータ」を指しているため(いつでも上書きされる可能性があるため)、 「いいえ」と答えます。ただし、「はい、通常の配列のように返します」と言う人もいます。

だから、私のジレンマに:

Tileオブジェクトへのポインタを保持する2D配列があります

Tile* map[128][128];

関数で配列を返す必要がありますか?なぜまたはなぜそうではないのですか?答えが「はい」の場合、どうすればよいですか?

編集:私は不明確でした。マップ変数を返し、配列内のポインターを別の関数で使用できるようにするgetterメソッドを作成したいと思います。

4

3 に答える 3

4

あなたはそれをすることができます...問題はあなたの発信者が今メモリを解放する責任があるということです。そして、彼はあなたがそれをどのように割り当てたかを知らないかもしれません。彼はfree()を呼び出す必要がありますか?消去[]?OSが提供する無料のルーチン?または、アプリ内の他のメモリキャッシュシステムによって提供されるものですか?

これを回避する2つの一般的な方法は次のとおりです。

  • 呼び出し元にメモリを割り当ててもらい、関数は単にメモリを設定します
  • C++配列クラスを使用します。ここでは、Tile*のstd::vectorを含むstd::vectorがある場合があります。これは、メモリの割り当て/割り当て解除を手動で処理する必要がないため、優れています。

しかし、それでは... Tile *インスタンスを解放するのは誰ですか?そして、どのAPIで?したがって、Tile *ではなく、Tileのベクトルのベクトルが必要になる可能性があります。

vector<vector<Tile>> map;
于 2012-12-11T02:04:35.467 に答える
3

あなたが得ている2つの答えは、これが可能な2つの異なる方法によるものです。

スタックベース-ローカルメモリ、割り当て解除され、返されたポインタが無効です

typedef int *(*TileGrid)[128];
Tile* map[128][128];
....
TileGrid GetTiles(){
    return map;
}

割り当てられたヒープ-ヒープに割り当てられ、関数の終了後に割り当て解除されません。この関数の呼び出し元が割り当てを解除します-安全です。

typedef int *(*TileGrid)[128];
TileGrid map = new Tile*[128][128];
....
TileGrid GetTiles(){
    return map;
}

推奨-C++の方法-サイズはコンパイル時定数であるため、ベクトルの代わりに配列(Tile*の代わりに真のC++の方法を使用しますstd::unique_ptr<Tile>が、一度に1つの問題があります。これらのコンテナーは自動的にメモリを管理し、std::arrayは通常の配列であるかのように使用できます。

typedef std::array<std::array<Tile*,128>,128> TileGrid;
TileGrid map ;
...
TileGrid& GetTiles(){
    return map;
}

高価なコピーを防ぐために参照によって戻ります。関数は単なるゲッターであり、オブジェクトはの所有権を維持するためmapです。

編集:ゲッター関数で修正

于 2012-12-11T02:12:04.433 に答える
1

C / C ++には、スタックとヒープの2種類のメモリがあります。通常、変数は一時ストレージであるスタックに割り当てられ、ループを終了したり関数から戻ったりするときなど、現在のスコープを終了するたびに再利用のマークが付けられます。

使用newするとヒープメモリが割り当てられ、使用するまで残りますdeleteが、メモリリークが発生しないように、すべてのnew呼び出しとdelete呼び出しを一致させるように注意する必要があります。C++でこの状況を管理するための多くの戦略があります。詳細については、「C++でのメモリ管理」をグーグルで検索できます。

単純なケースでは、ポインターを避け、stlコンテナーを使用してタイルの配列を作成することをお勧めします。たとえば、。のようなstd::vectorですvector< vector<Tile> > map。同じ角括弧構文を使用してマップにアクセスできます。たとえば、map[x][y] = Tile();このようにして、配列のメモリ割り当てと管理がベクトルクラスで処理されます。

于 2012-12-11T02:12:29.197 に答える