1

私は現在、私の古いプロジェクトをメモリセーフにする途中です。

このプロジェクトでは、独自のクラスのインスタンスへのポインターが取り込まれた 2D 配列がありますBlock

次のように宣言します。

Block* gemGrid[xMax][yMax];

後で次のように設定されます。

for(int i = 0; i<8; i++)
{
    for(int j = 0; j<8; j++)
    {
        //do stuff here
        gemGrid[i][j] = new Block(i,j, gridOffset);
    }
}

これはうまくいきます。

unique_ptr<Block>の代わりに の2D 配列を作成するというアイデアがありましたBlock*

私は次のように宣言することにしました:

unique_ptr<Block> gemGrid[xMax][yMax];

次のように入力します。

for(int i = 0; i<8; i++)
{
    for(int j = 0; j<8; j++)
    {
        gemGrid[i][j].reset( new Block(i,j, gridOffset));
    }
}

ただし、これを試してみると、コンパイラは 2 番目の for ループ ('j' インクリメント セクション) を完全に無視し、1 次元配列のみを作成することを決定します。

2D配列にC++問題がありますか? そして、sunique_ptrsへのポインターの2D配列に固執し、スコープ外になったときにこの配列が確実に削除されるようにする必要がありますか?Blockunique_ptr

4

1 に答える 1

4

C++ は、 の 2 次元配列に対して何の異論もありませんunique_ptr

あなたが提供する2つの選択肢は、私には本当の選択肢のようには見えません. のunique_ptr2 次元配列に があり、 usingのインスタンスBlock*を割り当ててそれらへのポインターを配列に格納すると、誰または何が のそれらのインスタンスを解放するのでしょうか? 確かにそうではありません。したがって、「それを行うべきか」に対する答えは、ほぼ確実に「いいえ」です。メモリ リークが発生するからです。xMax * yMaxBlocknewBlockunique_ptr

のインスタンスの 2 次元レイアウトを割り当てる最も「わかりやすい」方法は、 (組み込み配列を使用するか、利用可能な場合は)Blockの 2 次元配列を定義することです。それについて自分に合わないものを特定できれば、誰かがメモリ リークを回避するための古いコードの代替方法を提案できます。Blockstd::array

[上記のコメントへの回答] を実行Block gemGrid[xMax][yMax];すると、次のように、必要に応じて Block オブジェクトの 1 つへのポインターを取得できます&gemGrid[i][j]。ポインターの必要性は、メモリ割り当てとはまったく関係ありません。ポインター、割り当てられたオブジェクトにアクセスできるようにする手段newですが、割り当て方法に関係なく、オブジェクトへのポインターを取得できます。

于 2013-02-05T14:40:14.253 に答える