web-dev-qa-db-ja.com

動的に割り当てられた2D配列の削除

だから私はfree(pointer)pointerが指すすべてのスペースを解放するCのメモリ管理に慣れています。今、C++で簡単なことをしようとすると、混乱します。

これに似た方法で割り当てられたdoubleの2D配列がある場合

double** atoms = new double*[1000];
for(int i = 0; i < 1000; i++)
  atoms[i] = new double[4];

newによって割り当てられたヒープのメモリを解放する正しい方法は何でしょうか?

私の考えはもともとこれでした(私の脳はCで考えていたからです):

for(int i = 0; i < 1000; i++)
  delete atoms[i];
delete atoms;

しかし、私はdelete[]演算子の存在を忘れていたので、正しい方法は次のとおりであると信じています。

for(int i = 0; i < 1000; i++)
  delete[] atoms[i];
delete[] atoms;

deletedelete[]演算子の違いを理解することは重要ですか?または、ptr = new x[]で配列を割り当てるときはいつでも、delete[] ptrで配列の割り当てを解除する必要があると仮定できますか?

10
Alex

実際には、ポインターが指すポインターの配列は、メモリアドレスを保持するための整数データ型または数値の配列のままです。両方にdelete[]を使用する必要があります。

また、はい、new[]delete[]を意味します。

配列の配列を作成すると、実際には別の数値の配列のメモリアドレスを保持する数値の配列が作成されます。とにかく、両方とも数字の配列なので、delete[]で両方を削除します。

http://coliru.stacked-crooked.com/a/8a625b672b66f6ce

#include <iostream>

int main() {

    //Hey, pointers have a finite size, no matter the indirection level!
    std::cout << "sizeof(int*): " << sizeof(int*) << std::endl;
    std::cout << "sizeof(int**): " << sizeof(int**) << std::endl;
    std::cout << "sizeof(int***): " << sizeof(int***) << std::endl;

    //Create an array of pointers that points to more arrays
    int** matrix = new int*[5];
    for (int i = 0; i < 5; ++i) {
        matrix[i] = new int[5];
        for (int j = 0; j < 5; ++j) {
            matrix[i][j] = i*5 + j;
        }
    }

    //Print out the matrix to verify we have created the matrix
    for (int j = 0; j < 5; ++j) {
        for (int i = 0; i < 5; ++i) {
            std::cout << matrix[j][i] << std::endl;
        }
    }

    //Free each sub-array
    for(int i = 0; i < 5; ++i) {
        delete[] matrix[i];   
    }
    //Free the array of pointers
    delete[] matrix;

    return 0;
}
14
CinchBlue