web-dev-qa-db-fra.com

Supprimer un pointeur vers un pointeur (sous forme de tableau de tableaux)

J'ai ceci dans mon code:

double** desc = new double* [size_out];
for (int i = 0; i < size_out; i++)
    desc[i] = new double [size_in];

Comment supprimer ce desc?

Devrais-je:

delete [] desc;

ou

for (int i=0; i<size_out; i++)
    delete [] desc[i];
delete [] desc;

ou

for (int i=0; i<size_out; i++)
    delete [] desc[i];
delete desc;

?

31
yelo3

Des règles simples à suivre:

  • pour chaque allocation, il doit y avoir une désallocation (ex1 est donc faux)
  • ce qui a été alloué en utilisant new doit être libéré en utilisant delete, en utilisant new[] doit être désalloué à l'aide de delete[] et en utilisant malloc doivent être désalloués en utilisant free (ex3 a donc tort)

Conclusion, ex2 est OK.

21
Let_Me_Be

Votre code ne doit pas être compilé. Le type d'une nouvelle expression de tableau est un pointeur sur le type d'élément de tableau en cours de création (la valeur est un pointeur sur le premier élément du tableau alloué).

Donc, le type de new double**[size_out] est double ***.

Chaque fois que vous utilisez la forme tableau de new, vous devez utiliser la forme tableau de delete même si vous allouez uniquement un tableau de taille un.

double*** desc = new double**[size_out];
for (int i=0; i<size_out; i++)
    desc[i] = new double*[size_in];


for (int i=0; i<size_out; i++)
    delete[] desc[i];

delete[] desc;

Notez que vous n'avez toujours pas alloué de double, juste des pointeurs.

Vouliez-vous vraiment cela à la place?

double** desc = new double*[size_out];
for (int i=0; i<size_out; i++)
    desc[i] = new double[size_in];

for (int i=0; i<size_out; i++)
    delete[] desc[i];

delete[] desc;
21
CB Bailey

Votre suppression devrait refléter votre allocation.

Puisque vous avez utilisé new [] Pour allouer le tableau extérieur et new [] (En boucle) pour allouer les tableaux intérieurs, faites de même pour la suppression. C'est-à-dire: votre deuxième solution est correcte; delete [] Les tableaux intérieurs en boucle, et enfin le tableau extérieur via delete [] Également.

Cela dit, une ( beaucoup , beaucoup) meilleure solution en C++ serait d'utiliser un std::vector Imbriqué :

// Declaration and initialization:
vector<vector<double> > desc(size_out, vector<double>(size_in));

// No deletion!
18
Konrad Rudolph

Solution 2 est la bonne: chaque cellule pointe vers un tableau alloué dynamiquement qui doit être supprimé à l'aide de delete[]. Enfin, le tableau desc lui-même doit être supprimé à l'aide de delete[].

Bonus solution 4: évitez d'utiliser des tableaux et passez à std::vector<std::vector<double> >.

6
icecrime

Je ferais

for (int i=0; i<size_out; i++)
    delete [] desc[i];
delete [] desc;

pour chaque tableau alloué avec new [], vous disposez d'un delete [].

Et comme le dit Rupdolph: arrêtez d'utiliser les tableaux C et commencez à utiliser std::vector. Vous aurez moins de bugs (cent fois moins de bugs).

5
Stephane Rolland