comment fonctionne l'opérateur de suppression? Est-ce mieux alors gratuit()? Aussi, si vous faites ptr=new char[10]
, puis supprimez en utilisant delete ptr
, comment le pointeur sait combien d'emplacements à supprimer.Comment la suppression en C++ sait combien d'emplacements de mémoire à supprimer
Répondre
Il n'y a que l'opérateur delete
, free
Existe seulement en tant que fonction. Sous C++, vous êtes encouragé à utiliser new
/delete
sur malloc()
/free()
.
Il existe une "magie" interne dans l'opérateur de suppression. Lorsqu'un tableau est créé avec new[]
, la taille du tableau est stockée dans les métadonnées du bloc de mémoire. delete[]
utilise cette information.
Tout ceci dépend bien sûr du compilateur, de l'OS, de l'optimiseur et de l'implémentation.
Je suggère de remplacer 'new' par' new [] 'et' delete' par 'delete []'. – fredoverflow
Si vous utilisez par erreur 'delete ptr' au lieu de' delete [] ptr', la "magie" peut ou ne peut pas fonctionner correctement, encore une fois très dépendante de l'implémentation. –
@FredOverflow, @Mark: en effet, merci! – Vlad
Ajouter à @ la réponse de Vlad si vous allouez de la mémoire en utilisant les nouvelles [] sous forme de l'opérateur comme:
char *c = new char[10];
alors vous devez utiliser le formulaire de suppression correspondant:
delete[] c;
Vous devez Dites explicitement au compilateur d'utiliser les métadonnées lors du désallocation.
[EDIT]
Pourquoi vous ne pouvez pas utiliser char c []
Parce que le compilateur a besoin de connaître la taille, il a besoin de mettre de côté pour la variable c au moment de la compilation. Toutefois, l'utilisation du nouveau formulaire [] lui permet de reporter l'allocation jusqu'à l'exécution. Par conséquent, l'erreur du compilateur.
'char c [] = new char [10];' ne compile pas, vous devriez changer 'c []' en '* c'. – fredoverflow
cette instruction n'est pas légale, vous ne pouvez pas changer le pointeur d'un tableau de caractères. Je pense que vous vouliez dire char * c – shreyasva
Merci d'avoir signalé l'erreur. Fait la correction. – ardsrk
En C++, un constructeur est appelé en utilisant new, mais pas en utilisant malloc. De même, un destructeur est appelé lors de l'utilisation de delete, mais pas lors de l'utilisation de free. Si vous avez créé un tableau en utilisant MyClass * x = new MyClass [25], vous devez appeler delete [] x pour que le système sache qu'il supprime (et détruit) un groupe d'objets au lieu d'un seul.
L'implémentation calcule le nombre d'éléments à détruire (lors de l'utilisation de delete []) pour vous. Par exemple:
- new char [10] pourrait allouer quelques octets supplémentaires, mettre le nombre d'éléments au début, puis retourner le pointeur au premier élément après cela. delete [] pourrait alors regarder derrière le pointeur au nombre stocké
- stocker l'équivalent de std :: map < void *, size_t >, et nouveau T [n] créerait une clé avec le pointeur retourné, et une valeur avec le décompte. supprimer [] rechercherait le pointeur sur cette carte
- quelque chose de complètement différent. Ce n'est pas grave pour vous comment c'est fait, juste que c'est fait (et comme d'autres réponses l'ont souligné, utilisez delete [] avec new [] !!)
si vous faites un type non-tableau:
T t = new T;
// ...
delete t;
Il saura beaucoup à supprimer parce qu'il sait grand T est. Si vous faites un tableau:
T t* = new T[10];
// ...
delete [] t;
Il définira quelques informations supplémentaires avec l'allocation pour lui dire combien supprimer. Notez, nous utilisons delete [] t
avec le []
supplémentaire pour dire que c'est un tableau. Si vous ne faites pas cela, il va penser que c'est juste un T
et seulement libérer beaucoup de mémoire.
Toujours utiliser delete
si vous utilisez new
et free
si vous utilisez malloc
. new
fait 2 choses d'abord il alloue la mémoire, puis il construit l'objet. De même delete
appelle le destructeur, puis libère la mémoire. malloc\free
seulement traitent l'allocation de mémoire et la désallocation.
Ce n'est pas une question de mieux ou de pire. Les deux sont des opérations ayant le même but, l'allocation et la libération de la mémoire, mais généralement utilisées dans un contexte différent de C vs. C++. En outre, il existe des différences importantes entre les deux ensembles d'opérations:
new
/delete
sont les mots-clés C, et ne sont pas disponibles dans la langue Cnew
/delete
sont de type sécurité, alors quemalloc()
/free()
sont ne pas. Cela signifie que les pointeurs renvoyés parmalloc()
etfree()
sont des pointeursvoid
qui doivent être castés au bon type.new
/delete
soutenir implicitement l'allocation et la suppression tableau en utilisant la syntaxenew[]
etdelete[]
en utilisant des méta-données fournies par le compilateur,malloc()
/free()
ne prennent pas en charge cette syntaxe- application
new
/delete
à un type de classeT
appellera la constructeur et destructor respectivement deT
,malloc()
/free()
ne pas appeler le constructeur et destructor deT
malloc()
retourneraNULL
en cas d'épuisement de la mémoire,new
lancera une exception
Notez que pour éviter la corruption de la mémoire, la mémoire allouée à l'aide new
doit être libéré en utilisant delete
. La même chose vaut pour la mémoire allouée en utilisant malloc()
, qui devrait être libérée en utilisant free()
.
Répondant spécifiquement à votre question, l'opérateur de suppression invoque le destructeur, ce qui n'est pas le cas pour le destructeur; d'où la raison pour laquelle vous ne voulez pas mélanger malloc/free avec new/delete. Lorsque la bibliothèque du compilateur récupère la mémoire du tas, elle en saisit un peu plus que ce que vous lui demandez, ce qui inclut de l'espace pour sa gestion interne, certaines métadonnées et, si nécessaire, un remplissage.
Dites-vous 128 octets malloc, ou un nouveau tableau de huit objets de 16 octets.Le compilateur peut en effet saisir 256 octets, inclure un petit bloc de gestion de tas au début, enregistrer qu'il vous a donné 128 mais saisi 256, et vous renvoyer un décalage dans ce bloc 256 quelque part après son en-tête. Vous avez la garantie qu'à partir de ce pointeur, vous avez 128 octets que vous pouvez utiliser, mais si vous allez au-delà, vous pourriez avoir des problèmes. Les opérateurs gratuits et supprimés sous le capot prendront le pointeur que vous avez reçu, sauvegarderont un décalage connu, liront le bloc d'en-tête et sauront relâcher 256 octets dans le tas.
- 1. Comment free() sait combien de mémoire libérer?
- 2. Comment free() sait combien de mémoire libérer?
- 3. Le script Python sait combien de mémoire il utilise
- 4. Suppression de la mémoire dans C
- 5. Suppression complète des vues de la mémoire
- 6. Questions sur l'allocation de mémoire C et supprimer
- 7. C# - Suppression d'un fichier en permanence
- 8. Comment supprimer un arbre de recherche binaire de la mémoire?
- 9. supprimer ViewController de la mémoire
- 10. Suppression de données du flux de mémoire
- 11. Suppression par programmation des objets HtmlElement à l'aide de C#
- 12. Réutilisation de la mémoire en C++
- 13. Combien de mémoire allouer à un UIImageView 320x480?
- 14. quelqu'un sait comment supprimer des données de foxpro pack de pilote oledb avec C#
- 15. Comment puis-je dire à .NET combien de mémoire il devrait utiliser? et combien de mémoire devrait-il allouer à un processus?
- 16. Combien d'arguments a main() en C/C++
- 17. Accès à la mémoire supérieure à UINT_MAX * 4 en C?
- 18. supprimer & nouveau en C++
- 19. profilage de la mémoire en C#
- 20. Gestion de la mémoire en c objectif
- 21. Gestion de la mémoire en Objective-C
- 22. Comment supprimer les entrées de structure en C
- 23. Comment obtenir l'utilisation de la mémoire sous Windows en C++
- 24. Comment éviter la fuite de mémoire détectée suivante en C++?
- 25. C# chaîne regex, quelqu'un sait comment?
- 26. C# TPL Tâches - Combien en même temps
- 27. Comment trouver la taille actuelle (en mémoire) de la table?
- 28. Comment marquer des dossiers pour la suppression C#
- 29. allocation de mémoire en C
- 30. Fuite de mémoire en C
Je pense que vous voulez dire l'opérateur 'delete'. – SLaks
vous devez faire supprimer [] ptr sinon vous avez des ennuis. –
J'ai pris la liberté de clarifier votre titre, j'espère que cela ne vous dérange pas. Aussi, si vous vous posez des questions sur un compilateur et une plateforme spécifiques, il serait peut-être bon de l'inclure. Différents compilateurs peuvent avoir différentes façons de s'attaquer au problème que vous posez. – Skurmedel