2016-09-23 3 views
0

Я создал 3D-массив t динамически (t имеет тип int***). Теперь я пытаюсь удалить его.Каков правильный способ удаления динамического массива?

Я пришел через 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 

(t1 магазинов размера t[i] и t2 размера t[i][j])

, что это лучший способ?

+13

Ответ зависит от того, как память была выделена в первую очередь. – aschepler

+0

Off topic: 'int ***' не будет трехмерным массивом. Это будет массив массивов массивов. Они могут иметь действительно плохую производительность кеша. Если ты просто что-то ударишь, ОК. Если вам нужна скорость, рассмотрите массив 1D и оболочку, что делает его похожим на трехмерный массив. – 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 ] 

Другими словами, вы восстановили один из массивов, но вы просочились в большую часть памяти. К сожалению!

С другой стороны, если вы используете версию кода удаления для цикла, вы в конечном итоге восстанавливаете всю память, потому что вы прошли все указатели и освободили каждый выделенный массив.

Вообще говоря, каждое распределение должно иметь соответствующее освобождение, поэтому, если вы вызываете new[] несколько раз, вам нужно позвонить delete[] равное количество раз.

Как уже отмечалось в некоторых комментариях, есть, вероятно, более эффективные способы управления 3D-массивом, чем использование int ***. Общая тенденция на 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; 
} 
Смежные вопросы