2016-03-21 9 views
0

SO [C内のポインタの2次元アレイが++どのように割り当てること] [1]、受け入れ答えも縮小する方法の正しい手順のメモを行い、問題のその配列を割り当て、削除します。つまり、含まれているポインタ、行配列、列配列をすべて別々に正しい順序で削除するよう注意してください。したがって、私はセルオートマトンシミュレーションプログラムでこの2Dアレイをうまく使用しています。しかし、私はこの配列のメモリ管理を正しくすることはできません。私は上記の参照以外のこれを行う方法のためのSOの答えが表示されません。明らかC++オブジェクトへのポインタの2次元配列の割り当てを解除し、削除する方法

for (int i = 0; i < rows; i++) { 
    for (int j = 0; j < cols; j++) { 
     matrix_0[i][j] = NULL; 
    } 
} 
delete [] matrix_0; 
matrix_0 = NULL; 

Object*** matrix_0 = new Object**[rows]; 
    for (int i = 0; i < rows; i++) { 
     matrix_0[i] = new Object*[cols]; 
    } 

マイ無益試み(複数可)を適切に解除割り当てる以下の通りである上記アレイ(Valgrindのに応じて)次のよう

私は2次元配列を割り当てます参照[1]が示唆しているように、行と列の一部が欠落しています。私が見逃していることを私に見せてもらえますか?前もって感謝します。

[1]:(2009年11月20日)How to allocate a 2D array of pointers in C++

+6

'std :: vector > vector_of_objects; – SergeyA

+0

オブジェクトの2次元配列またはポインタの2次元配列に慣れていますか? –

+0

@ R Sahu:基本クラスオブジェクトへのポインタの2D配列で、さまざまなセルオートマトン由来オブジェクトの多態的な振る舞いを利用するように設定されています。 – Chris

答えて

5

あなたはこれでやって削除するのトンを持っている:

for (int i = 0; i < rows; i++) { 
    for (int j = 0; j < cols; j++) { 
     delete matrix_0[i][j]; // delete stored pointer 
    } 
    delete[] matrix_0[i]; // delete sub array 
} 
delete [] matrix_0; //delete outer array 
matrix_0 = NULL; 

彼らは後になくなっているので、matrix_0除くNULL何もする必要はありません削除する。

これは恐ろしく不必要です。 Use a std::vectorと、含まれているオブジェクトへのポインタを真剣に再考してください。

std::vector<std::vector<Object*>> matrix_0(rows, std::vector<Object*>(cols)); 

あなたが欲しいものを取得し、

for (int i = 0; i < rows; i++) { 
    for (int j = 0; j < cols; j++) { 
     delete matrix_0[i][j]; // delete stored pointer 
    } 
} 

に削除作業を軽減しかし、速度はOPの目標の一つであるためunique_ptrを格納するSergeyAの提案、std::vector<std::vector<std::unique_ptr<Object>>> matrix_0;は0

に必要な欠失を低減もう1つ改善があります:

std::vector<std::unique_ptr<Object>> matrix_0(rows * cols); 

アクセスは、これは現在、舞台裏で起こって見えない数学やポインター逆参照のために目に見える数学のビットを取引

matrix_0[row * cols + col]; 

です。重要な部分は、ベクトルが空間的局所性を高め、キャッシュミスの数を減らすメモリの素敵な連続ブロックとして格納されることです。メモリ全体に散らばっているObjectsへのポインタに起因するミスを助けることはできませんが、いつも勝つことはできません。

配列対vector上の注意事項。

std::vector<std::unique_ptr<Object>> matrix_0(rows * cols); 

すべてvectorがあるが、終わりをマークすると、夫婦他のポインタへのポインタと最後の場所です:vectorが構築されると、この場合には、すべてここ一発で行われています使用された場所。データ配列へのアクセスは、newで作られた動的配列へのアクセスと変わりません。インデックス演算子[]を使用すると、配列上で[]を使用する場合と全く同じようにdata_pointer + indexまでコンパイルされます。JavaのVectorのように同期などはありません。それは単純な生の数学です。

事前割り当てされたすべての事前割り当て済みのvectorと比較すると、2つのポインタのメモリが必要になります。その結果、表示される可能性が高いメモリ管理に苦労することはありません。

+0

はい、恐ろしいですが、必要とされた、私は、スピードの懸念によって言われました。迅速かつ正確な(テスト済みの)回答をいただきありがとうございます。 – Chris

+1

ベクトルの構築時に十分なスペースを確保すると、 'std :: vector >'との間の速度差は、「検出不能」と「無視できる」の間にある可能性があります。 –

0

ポインタをNULLに設定する前に、まずdeleteを指定する必要があります。列内のすべてのポインタが削除された後、行はdelete[]になり、すべての要素が削除されて消えたので、NULLに設定することができます。

関連する問題