Dupliqué possible: strong>
(POD) Mémoire de libération: est supprimée [] égale à supprimer? p>fait
supprime code> désallocise les éléments au-delà du premier dans un tableau? p>
int *p = new int[n]; delete p; delete[] p; free p;
10 Réponses :
Pour les types primitifs, tels que CHAR, INT, y a-t-il une différence entre: p> blockQuote>
Je dirais que vous obtiendrez un comportement indéfini. Donc, vous ne devriez pas compter sur un comportement stable. Vous devez toujours utiliser de nouvelles / supprimées, neufs [] / Suppr [] et Malloc / Gratuit paires. P>
Non, M "Mise en œuvre définie" est le terme utilisé par l'ISO lorsqu'un fournisseur de compilateur doit documenter leur choix. Il n'y a pas de telle obligation dans ce cas. Nasal Lesamons sont autorisés sans avertissement.
Il a déjà été discuté ici: Stackoverflow.com/Questtions/1553382/...
Je ne savais pas que ce terme utilisé par l'ISO. Fixé.
C'est un comportement indéfini. Par conséquent, l'anser est: Oui, il pourrait y avoir un danger. Et il est impossible de prédire exactement ce qui va déclencher des problèmes. Même si cela fonctionne une fois, cela fonctionnera-t-il à nouveau? Cela dépend-il du type? Compte d'élément? P>
Ce comportement indéfini (le plus probablement va corrompre le tas ou le programme immédiatement) et vous ne devriez jamais le faire. Seule la mémoire libre avec une primitive correspondant à celle utilisée pour allouer cette mémoire. P>
violation de cette règle peut conduire à un fonctionnement correct par coïncidence, mais le programme peut casser une fois que tout est modifié - le compilateur, l'exécution, les paramètres du compilateur. Vous ne devriez jamais s'appuyer sur un tel fonctionnement approprié et vous y attendez. P>
Suppr [] code> utilise des données de service spécifiques au compilateur pour déterminer le nombre d'éléments. Habituellement, un bloc plus gros est attribué lorsque
Nouveau [] code> est appelé, le numéro est stocké au début et l'appelant est donné l'adresse derrière le numéro stocké. Quoi qu'il en soit,
Suppr [] code> s'appuie sur le bloc étant attribué par
Nouveau [] code>, pas rien d'autre. Si vous associez quelque chose, sauf
Nouveau [] code> avec
Suppr [] code> ou vice versa que vous rencontrez un comportement non défini. P>
Lire la FAQ: 16.3 puis-je libérer () Les pointeurs alloués à nouveau? Puis-je supprimer des pointeurs alloués avec malloc ()? p>
est-il important dans le cas ci-dessus, voir que tous les éléments de S sont alloués contiguës, et il ne devrait pas être possible de supprimer une partie de la matrice? P> blockQuote>
Oui, c'est. P>
Comment supprimer [] déduire le nombre d'objets au-delà du premier, cela ne signifie-t-il pas qu'il doit connaître la taille de la région de mémoire allouée? P> blockQuote>
Le compilateur doit savoir. Voir FAQ 16.11 P>
Parce que le compilateur stocke cette information. P> blockQuote>
Ce que je veux dire, c'est que le compilateur nécessite différents
Supprimer code> S pour générer un code de conservation approprié. J'espère que cela est clair maintenant. P>
Si le compilateur stocke des informations requises pour Suppr [], pourquoi ne peut-il pas être suffisamment intelligente pour fonctionner avec une suppression simple?
"Parce que le compilateur stocke cette information." C'est une charge de non-sens. L'opérateur ne conserve-t-il que les doublons de toutes les allocations avec le nombre d'éléments pour les allocations de réseau? Non, cela semble improbable et très inefficace pour moi.
@Anacrolix: Je me réfère à des informations sur le comptage de livres que le compilateur gère pour les allocations / offlocations. Je ne suis pas sûr de ce que vous entendez par des doublons. Vs utilisé pour conserver le nombre d'éléments de tableau juste avant le début de la matrice. Pouvez-vous fournir des implémentations alternatives?
@Vanja: Pour une simple nouvelle / supprime, des informations beaucoup moins de comptabilité sont nécessaires. Pour les tableaux, d'autre part, le compilateur doit allouer un peu plus que ce que vous utiliserez.
@Vanja: Si vous souhaitez utiliser la vanille Supprimer pour un seul objet et un pointeur à un tableau d'objets, le compilateur ne le saurait pas de l'autre. FAQ 16.11
Ce n'est pas le compilateur qui stocke cette information, c'est le temps d'exécution. Veuillez mettre à jour votre réponse, la différence est importante. Le compilateur ne peut pas stocker ces informations car il n'est pas connu au moment de la compilation.
@Dircrange: en fait, puisque vous pouvez remplacer les opérateurs de nouveaux / Supprimer, vous pouvez stocker les informations comme vous qui. Effectivement, la plupart des implémentations stockent la taille de la matrice juste avant le premier élément afin que vous puissiez généralement le trouver avec un petit décalage (négatif).
Cela conduira à des accidents de programmation ou un comportement même pire! P>
pour les objets alloués avec pour les objets alloués avec pour les objets alloués avec Sachez également que pour tous ces cas, il est illégal de supprimer / libérer un pointeur déjà supprimé / libéré une seconde fois. nouveau code> vous
Supprimer code>; p>
Nouveau [] code> vous
Suppr [] code>; p>;
masloc () code> ou
calloc () code> vous
gratuit () code>; / p>
Gratuit code> peut également être appelé avec NULL. Calling
Supprimer / Supprimer [] Code> avec NULL est légal. p>
C'est bien connu. Je demande des cas spécifiques.
"" GRATUIT () libère l'espace mémoire pointé par PTR, qui a dû être renvoyé par un appel précédent à Malloc (), CalloC () ou Realloc (). Sinon, ou si libre (PTR) a déjà été appelé auparavant, un comportement indéfini se produit. Si PTR est NULL, aucune opération n'est effectuée. "" ". Notez la clause sur NULLL. De Linux.die.net/man/3/free , mais je n'ai pas de spécification C formelle C pratique.
Il n'y a pas de cas spécifique. Ce n'est pas permis.
Oui, il y a un vrai danger pratique. Même les détails de la mise en œuvre, rappelez-vous que opérateur Nouveau / opérateur Supprimer code> et
Opérateur Nouveau [] / Opérateur Supprimer [] code> Les fonctions peuvent être remplacées complètement indépendamment. Pour cette raison, il est sage de penser à
nouveau / suppression code>,
nouveau [] / supprimer [] code>,
malloc / libre code> etc.) , des méthodes complètement indépendantes d'allocaton de mémoire, qui n'ont absolument rien en commun. P>
Même s'ils peuvent être remplacés de manière indépendante, il est généralement conseillé de les remplacer tous (comprenant le placement nouveau) ou aucun du tout.
Oui peut-être. Mais même s'ils sont tous remplacés, ils peuvent toujours allouer de la mémoire de différents pools de mémoire avec différents principes de gestion de la mémoire (pour des raisons évidentes, comme les tailles de blocs dans les fonctions «[]» sont variable, même pour le même type d'objet, tout en restant [] 'Fonctions qu'ils ne sont pas), faisant ainsi une utilisation croisée complètement infaisable.
Bien que cela puisse sembler de manière logique que vous puissiez mélanger de nouvelles [] et libres ou de suppression au lieu de supprimer [], cela se situe sous l'hypothèse sur le compilateur étant assez simpliste, c'est-à-dire que cela utilisera toujours MALLOC ( ) Pour mettre en œuvre l'allocation de mémoire pour les nouveaux []. P>
Le problème est que si votre compilateur dispose d'un optimiseur suffisamment intelligent, cela pourrait voir qu'il n'y a pas de "Supprimer []" correspondant au nouveau [] pour l'objet que vous avez créé. Il pourrait donc supposer que cela peut récupérer la mémoire de n'importe où, y compris la pile afin de sauvegarder le coût d'appel du véritable malloc () pour le nouveau []. Ensuite, lorsque vous essayez d'appeler gratuitement () ou du mauvais type de Supprimer, il est susceptible de dysfonctionnement difficile. P>
Supprimer réalise les éléments au-delà du premier dans un tableau? p>
Non. Supprimer ne distribuera que le premier élément quel que soit le compilateur que vous faites cela. Cela peut travailler dans certains cas, mais c'est co-accessoire. P>
est-il important dans le cas ci-dessus, voir que tous les éléments de s sont alloués contiguë, et il ne devrait pas être possible de supprimer une partie de la matrice? P> BlockQuote>
dépend de la façon dont la mémoire est marke aussi libre. Encore une fois la mise en œuvre dépendante. P>
Pour des types plus complexes, supprimerait appeler le destructeur d'objets au-delà du premier? P> BlockQuote>
Non. Essayez ceci: p>
xxx pré> Comment supprimer [] déduire le nombre de Objets au-delà du premier, ne serait pas cela signifie qu'il doit connaître la taille de la Région de mémoire allouée? P> BlockQuote>
Oui, la taille est stockée un endroit. Où il est stocké dépend de la mise en œuvre. Exemple, l'allocateur pourrait stocker la taille dans un en-tête précédant l'adresse allouée. P>
Et si la région de la mémoire était alloué avec un surplomb pour raisons de performance? Par exemple un pourrait supposer que tous les allocateurs ne sont pas tous fournirait une granularité d'un octet unique. Alors n'importe quel particulier L'allocation pourrait dépasser le nécessaire taille pour chaque élément par un tout élément ou plus. p> BlockQuote>
C'est pour cette raison que l'adresse renvoyée est faite pour aligner les limites des mots. Le "surplomb" peut être vu à l'aide de la taille de l'opérateur et s'applique également aux objets sur la pile. P>
Pour les types primitifs, tels que CHAR, INT, y a-t-il une différence entre ...? P> BlockQuote>
Oui. MALLOC et Nouveau pourraient utiliser des blocs de mémoire séparés. Même si ce n'était pas le cas, c'est une bonne pratique de ne pas supposer qu'ils sont les mêmes. P> blockquote>
Je pense que vous voulez dire que New et Malloc pourrait utiliser différents allocateurs?
Il peut y avoir du "surhang" supplémentaire. L'alignement a à voir avec l'adresse de départ du bloc. Il est possible que pour des raisons de performance, un allocator utilise plus de mémoire. Par exemple, il existe des allocateurs qui n'allocient que des blocs avec des tailles qui sont une puissance de 2. Si vous demandez 33 octets, vous obtenez un bloc de taille 64. Cela facilite la gestion de la liste des blocs alloués et gratuits beaucoup plus facilement / plus rapides, à la dépense d'utilisation accrue de la mémoire. Il peut même être possible que l'allocateur connaisse la taille de l'allocation de juste l'adresse de départ, nier la nécessité de stocker des informations supplémentaires.
@Anacrolix: Vous pouvez être juste bien que l'allocator est généralement le système d'exploitation. Ma réponse repose principalement sur l'exemple d'allocator en K & R ... Je suppose que chaque allocator obtient une partie différente de la mémoire du système d'exploitation.
Raymond Chen (Microsoft Developer) dispose d'un article en profondeur couvrant Scaler vs. Seletes vectoriels, et donne des antécédents aux différences. Voir: P>
http://blogs.msdn.com/oldnewthing /Rarchive/2004/02/03/66660.aspx P>
Étape 1 Lisez ceci: What-Is-the-différence - entre-neuf-Suppren-and-Malloc-Free
Vous regardez uniquement ce que vous voyez du côté du développeur.
Ce que vous n'envisageez pas, c'est comment la LIB STD Gestion de la mémoire. P>
La première différence est que le nouveau et Malloc allouent MEMROY de deux zones différentes en mémoire (Nouveauté de Freestore et Malloc de Heap (Ne vous concentrez pas. Sur les noms, ils sont essentiellement des tas, ceux-ci sont juste là des noms officiels de la norme)). Si vous allouez d'un et de désaffecter à l'autre, vous gênerez les structures de données utilisées pour gérer la mémoire (il n'y a pas de gurantie, ils utiliseront la même structure pour la gestion de la mémoire). P>
Quand vous allouez Un bloc comme celui-ci: p>
Memory Value Comment 0x08 0x40 // Chunk Size 0x16 0x10000008 // Free list for Chunk size 40 0x24 0x08 // Block Size 0x32 ?? // Address returned by New. 0x40 0x08 // Pointer back to head block. 0x48 0x0x32 // Link to next item in a chain of somthing.
Je ne crois pas que ce soit un duplicata, je pose des questions différentes très spécifiques et je n'ai aucun intérêt pour les connotations de montage
Non, c'est un duplicata. Vous demandez à la exacte i> la même question », ai-je autorisé à remplacer Supprimer pour Suppr []". Et la réponse est la même que dans tous les threads précédents où la même chose a été posée: "Non, vous n'êtes pas. C'est un comportement indéfini".
Si vous voulez demander à Autres questions i> Comment supprimer [] savoir combien d'objets à supprimer », puis créez une nouvelle question pour cela, donnez-lui son propre titre. Pour que d'autres personnes qui veulent Demander la même chose sera capable de le trouver.