web-dev-qa-db-fra.com

La différence entre delete et delete [] en C++

Doublon possible: _
delete vs delete [] opérateurs en C++

J'ai écrit une classe qui contient deux pointeurs, l'un est char* color_ et l'autre dans vertexesset* vertex_vertexesset est une classe que j'ai créée. Dans le destructeur que j'ai écrit au début

delete [] color_;
delete [] vertex_;

Quand il est venu au destructeur, il m'a donné une faute de segmentation.

Puis j'ai changé le destructeur en:

delete [] color_;
delete vertex_;

Et maintenant ça marche bien. Quelle est la différence entre les deux?

32
SIMEL

Vous delete [] lorsque vous new un type de tableau et delete lorsque vous ne l’avez pas Exemples:

typedef int int_array[10];

int* a = new int;
int* b = new int[10];
int* c = new int_array;

delete a;
delete[] b;
delete[] c; // this is a must! even if the new-line didn't use [].
58
etarion

delete et delete[] ne sont pas la même chose! Wikipedia explique ceci, si brièvement. En bref, delete [] appelle le destructeur sur chaque élément du tableau alloué, alors que delete suppose que vous avez exactement une instance. Vous devriez allouer des tableaux avec new foo[] et les supprimer avec delete[]; pour les objets ordinaires, utilisez new et delete. Utiliser delete[] sur un non-tableau pourrait causer des dégâts.

14
EmeryBerger
  • Si vous allouez avec malloc (), vous utilisez free ()
  • Si vous allouez avec new vous utilisez delete
  • Si vous allouez avec new [], vous utilisez delete []
  • Si vous construisez avec placement-new vous appelez le destructeur directement
  • S'il est logique d'utiliser le vecteur plutôt que le nouveau [], utilisez-le
  • S'il est judicieux d'utiliser des pointeurs intelligents, utilisez-les et ne vous donnez pas la peine d'appeler supprimer (mais vous aurez toujours besoin d'appeler à nouveau). La suppression correspondante sera dans le pointeur intelligent.

https://isocpp.org/wiki/faq/freestore-mgmt

7
CashCow

Vous devez utiliser delete [] si vous avez alloué de la mémoire sur le tas avec l'opérateur new [] (par exemple, un tableau dynamique).

Si vous avez utilisé operator new, vous devez utiliser operator delete, sans les crochets.

Il n'est pas lié à la suppression d'un type intégré ou d'une classe personnalisée.

5
Francesco

Lorsque nous voulons libérer une mémoire allouée à un pointeur sur un objet, "supprimer" est utilisé. 

int * p;
p=new int;

// now to free the memory 
delete p;

Mais quand nous avons alloué de la mémoire pour un tableau d'objets comme 

int * p= new int[10]; //pointer to an array of 10 integer

puis pour libérer de la mémoire égale à 10 entiers:

 delete []p;

NOTE: On peut libérer la mémoire même avec delete p;, mais cela ne libérera que la mémoire du premier élément.

4
Dorababu Meka

Si vous avez Effective C++ part 1 , reportez-vous à la rubrique n ° 5: utilisez le même formulaire pour les utilisations correspondantes de new et delete.

1
yasouser

Et maintenant ça marche bien. 

Plus par chance, si c'est le cas, et êtes-vous certain que cela fonctionne vraiment?

Le destructeur de chaque objet doit être appelé, l'opérateur delete[] utilise les informations définies par new[] pour déterminer le nombre d'objets à détruire. Ainsi, alors que delete peut à lui seul restaurer la mémoire (que cela dépende ou non de la mise en œuvre), il ne peut pas appeler le destructeur pour chaque objet alloué.

Il est possible que les informations sur la manière dont les objets ont été alloués soient incluses lorsque new ou new[] est appelé, de sorte que la forme correcte de suppression soit utilisée indépendamment, mais dépend également de l'implémentation et n'est pas garantie.

0
Clifford

Raymond Chen décrit de manière détaillée le fonctionnement de la suppression du scaler et du vecteur dans son blog intitulé Mismatching scalar and vector new and delete .

Voici un lien vers l'article InformIT qui est mal lié dans l'article ci-dessus: http://www.informit.com/articles/article.aspx?p=30642

0
Tergiver

en outre (évidemment, ma vitesse de frappe devrait être améliorée :), considérez ne pas utiliser pointeurs si vous ne le faites pas vraiment devez le faire. par exemple. char* peut être remplacé par std::string et si votre membre vertexesset n'est pas polymorphe, vous pouvez en faire un objet membre. Dans ce cas, vous n’auriez pas besoin de delete du tout

0
davka