2017-07-14 18 views
0

私は現在、生のポインタを使用する必要があるような特定のAPIを使用していますが、ポインタの特定の配置を考えれば、メモリをクリアしてそうする際の未定義の動作。この2次元配列のメモリを解放する

double *data1 = new double[rows*columns]; 
double **data2 = new double*[rows]; 
data2[0] = data1; // Point to first row 

for (int i = 1; i < columns; i++) { 
    data2[i] = data2[i - 1] + rows; 
} 

私は以下のような試みをしましたが、それは正しいとは思いません。

for(int i = 0; i < rows; i++) { 
    delete [] data2[i]; 
} 
delete [] data2; 
delete [] data1; 
+0

あなたは[ 'のstd :: vector'](http://en.cppreference.com/w/cpp/container/vector)を使用して考えがあります代わりに? –

+2

2つの 'new'がある場合は、2つの' delete'が必要です。あなたの例は '行+ 2 'の削除を持っています。基本的に、あなたが持っているニュースや削除の数を数えれば、それらは等しくなるはずです。 –

+0

ここで削除の順序が違いますか? – Alexander

答えて

0

誰が所有していますか?

オブジェクトを削除する方法を決定する質問です。

あなたがやっていると思うのは、2次元配列のデータを保持するために1つの大きな配列を作成し、各行の先頭へのポインタを保持する別の配列を作成することです。

これは2つのニュース、したがって2つの削除です。

このように視覚化する方が簡単かもしれません:

struct matrix_view 
{ 
    int rows, columns; 

    // this pointer owns a block of doubles 
    double* entire_buffer = nullptr; 

    // this pointer owns a block of pointers, but not the memory 
    // they point to 
    double** row_pointers = nullptr; 
}; 

matrix_view create_matrix(int rows, int columns) 
{ 
    auto result = matrix_view{ rows, columns, nullptr, nullptr }; 

    auto size = rows * columns; 
    result.entire_buffer = new double [size]; 
    result.row_pointers = new double* [rows]; 
    auto first = result.entire_buffer; 
    auto last = first + size; 
    auto dest = result.row_pointers; 
    while (first != last) { 
     *dest++ = first; 
     first += columns; 
    } 
    return result; 
} 

void destroy_matrix(matrix_view m) 
{ 
    // always destroy in reverse order 

    delete [] m.row_pointers; 
    delete [] m.entire_buffer; 
}