2016-09-23 15 views
0

3D配列tを動的に作成しました(tint***です)。今私はそれを削除しようとしています。ダイナミックアレイを削除する適切な方法は何ですか?

私は2つの提案に遭遇してきた: 一つは、単に

delete[] t; 

を行うと、どうやら、それはすべてを削除することです。

他には最良の方法は何か

for(int i=0;i<3;i++) 
{ 
    for(int j=0;j<t1[i];j++) 
    { 
     delete[] t[i][j];//delete all 1D array 
    } 
    delete[] t[i];//delete all 2D array 
} 
delete[] t;//delete the 3D array 

t[i]t2t[i][j]の大きさのt1店舗サイズ)

ような何かをしているのですか?

+13

答えはメモリが最初の場所に配分された方法によって異なります。 – aschepler

+0

トピックオフ: 'int ***'は3D配列ではありません。これは配列の配列の配列になります。これらは本当に悪いキャッシュパフォーマンスを持つことができます。何かを叩いているだけなら、OK。スピードが必要な場合は、1次元配列と3D配列のように見えるラッパーを考えてみましょう。 – user4581301

+2

最初に 'std :: vector'を使わないのはなぜですか? – Jarod42

答えて

5

@ascheplerはコメントで言及しているように、これはメモリの初期割り当て方法によって異なります。

int*** t = new int**[dim1]; 
for (int i = 0; i < dim1; i++) { 
    t[i] = new int*[dim2]; 
    for (int j = 0; j < dim2; j++) { 
     t[i][j] = new int[dim3]; 
    } 
} 

あなたは、このようにメモリを割り当てた場合は、メモリはこのようなものになります。:今すぐ

     [ 0 ] --> [ 0 ][ 1 ][ 2 ][ 3 ] 
       +---> [ 1 ] --> [ 0 ][ 1 ][ 2 ][ 3 ] 
       |  [ 2 ] --> [ 0 ][ 1 ][ 2 ][ 3 ] 
       | 
t ---> [ 0 ] [ 1 ] 
      | 
      |  [ 0 ] --> [ 0 ][ 1 ][ 2 ][ 3 ] 
      +---> [ 1 ] --> [ 0 ][ 1 ][ 2 ][ 3 ] 
       [ 2 ] --> [ 0 ][ 1 ][ 2 ][ 3 ] 

を、あなただけの

を書くと仮定私は、あなたはおそらく、このようにメモリを割り当てられていると仮定します
delete[] t; 

あなたがこれを行う場合、メモリは次のようになります。

     [ 0 ] --> [ 0 ][ 1 ][ 2 ][ 3 ] 
         [ 1 ] --> [ 0 ][ 1 ][ 2 ][ 3 ] 
         [ 2 ] --> [ 0 ][ 1 ][ 2 ][ 3 ] 

t ---> xxx 

       [ 0 ] --> [ 0 ][ 1 ][ 2 ][ 3 ] 
       [ 1 ] --> [ 0 ][ 1 ][ 2 ][ 3 ] 
       [ 2 ] --> [ 0 ][ 1 ][ 2 ][ 3 ] 

つまり、アレイの1つを再利用しましたが、メモリの大半がリークしました。おっとっと!

一方、forループバージョンの削除コードを使用すると、すべてのポインタを通過して割り当てられた各配列が解放されたため、すべてのメモリが再利用されます。

一般に、すべての割り当てには割り当て解除が必要です。したがって、new[]を何回か呼び出した場合は、delete[]を同じ回数呼び出す必要があります。

コメントの中には、int ***を使用するよりも、おそらく3Dアレイを管理する方が良い方法があることが指摘されています。 C++の一般的な傾向は、オブジェクトを使用してメモリを可能な限り自動的に管理することです。 Boost multi_arrayタイプを調べるか、エントリを行優先順に格納するstd::vectorの周りにラッパーを書くことを検討してください。

0

メモリを割り振るだけで、メモリを適切に割り振ることが非常に重要です。 それを削除しているときに限り、ヒープ上のマルチ薄暗い配列を作成している間、私たちはとても慎重でなければなりません:

#include <iostream> 
using std::cout; 
using std::endl; 

int main() 
{ 

    int*** ptrInt = new int**[3]; 

    for(int i(0); i < 3; i++) 
     ptrInt[i] = new int*[3]; 

    for(int i = 0; i < 3; i++) 
    { 
     for(int j(0); j < 3; j++) 
      ptrInt[i][j] = new int[3]; 
    } 


    for(int i = 0; i < 3; i++) 
    { 
     for(int j(0); j < 3; j++) 
      for(int k(0); k < 3; k++) 
       ptrInt[i][j][k] = k; 
    } 

    for(int i = 0; i < 3; i++) 
    { 
     for(int j(0); j < 3; j++) 
      for(int k(0); k < 3; k++) 
       cout << "ptrInt[" << i << "][" << j << "][" << k << "]: " << ptrInt[i][j][k] << endl; 
    } 

    // now freeing memory: 

    for(int i = 0; i < 3; i++) 
    { 
     for(int j(0); j < 3; j++) 
      delete[] ptrInt[i][j]; 
     delete[] ptrInt[i]; 
    } 
    delete[] ptrInt; 
    ptrInt = NULL; // if we call delete again on a null pointer it's ok 


    cout << endl; 
    return 0; 
} 
関連する問題