7
votes

Comment la suppression en C ++ savait-elle combien d'emplacements de mémoire pour supprimer

Comment fonctionne l'opérateur de suppression? Est-ce mieux alors libre () ?. Également si vous faites pTR = nouveau caractère [10] , puis supprimez à l'aide de Supprimer le PTR , comment le pointeur sache-t-il combien d'emplacements à supprimer.


5 commentaires

Je pense que vous voulez dire l'opérateur Supprimer .


Vous devez supprimer [] PTR sinon vous avez des ennuis.


J'ai pris la liberté pour clarifier votre titre, j'espère que cela ne vous dérange pas. De plus, si vous vous demandez sur un compilateur et une plate-forme spécifiques, cela pourrait être bon d'inclure cela. Différents compilateurs peuvent avoir différentes façons de résoudre le problème que vous posez.


g ++ sur fedora, aussi ce titre fonctionne mieux


Voir stackoverflow.com/questions/1616937/... et Stackoverflow.com/questions/197675/... .


7 Réponses :


18
votes

Il n'y a que Supprimer opérateur, gratuit uniquement comme fonction. Sous C ++, vous êtes encouragé à utiliser Nouveau / Supprimer sur MALLOC () / gratuit () .


Il y a une "magie" interne dans l'opérateur de suppression. Lorsqu'un tableau est créé avec Nouveau [] , la taille de la matrice est stockée dans les métadonnées au bloc de mémoire. Supprimer [] utilise ces informations.

Tout cela est bien sûr compilateur, OS-, optimiseur et dépendant de la mise en œuvre.


5 commentaires

Je suggère de changer nouveau à Nouveau [] et Supprimer à Suppr [] .


Si vous utilisez par erreur Supprimer le PTR au lieu de Suppr [] PTR , la "magie" peut ou non fonctionner correctement, à nouveau très en attente de la mise en œuvre.


Je ne comprendrai jamais pourquoi C ++ passe la taille des matrices autour de l'interne, mais ne vous donne pas accès à eux, vous obligeant à transmettre des tailles de réseau par vous-même.


@Blueraja: Si vous créez une matrice née Note longue, C ++ n'est pas obligé d'attribuer exactement n octets pour ce tableau - il peut attribuer davantage, par exemple pour assurer l'alignement.


@Blueraja: Parce que c ++ n'est pas requis pour connaître la taille de la matrice. La mise en œuvre concrète peut savoir quelle est la taille de la matrice dans octets , mais je ne connais pas la matrice maximale index (parce que cela ne se soucie pas de la taille de l'article). D'autre part, si vous avez besoin de connaître la taille aussi, vous avez peut-être besoin de std :: vecteur au lieu du tableau?



2
votes

Ajout de la réponse de @ Vlad Si vous allouez de la mémoire à l'aide de la nouvelle [] forme de l'opérateur comme: xxx pré>

, alors vous devez utiliser le formulaire de suppression correspondant: P>

delete[] c;


3 commentaires

Char c [] = nouveau caractère [10]; ne compile pas, vous devez modifier c [] sur * C .


Cette déclaration n'est pas légale, vous ne pouvez pas modifier le pointeur d'un tableau de caractères. Je pense que tu voulais dire que Char * c


Même si vous faites Supprimer C , je parie que cela fonctionnera. Ne me demandez pas pourquoi :)>



3
votes
  1. en C ++, un constructeur est appelé à l'aide de nouveaux, mais pas lors de l'utilisation de MALLOC. De même, un destructeur est appelé lorsque vous utilisez Supprimer, mais pas lors de l'utilisation libre.

  2. Si vous avez un nouveau-e ed un tableau à l'aide de myClass * x = nouvelle myClass [25], alors vous devez appeler Suppr [] x, de sorte qu'ils sait que le système sait qu'il supprime (et détruire) un groupe de objets au lieu d'un seul.


0 commentaires

3
votes

La mise en œuvre fonctionne le nombre d'éléments pour détruire (lorsque vous utilisez Supprimer []) pour vous. Par exemple:

  • Nouveau Char [10] pourrait attribuer quelques octets supplémentaires, mettre le nombre d'éléments au début, puis renvoyer le pointeur au premier élément après cela. Supprimer [] pourrait alors regarder derrière le pointeur sur le compte stocké
  • Stockez l'équivalent de std :: map et le nouveau t [n] créerait une clé avec le pointeur retourné et une valeur avec le compte. Supprimer [] rechercherait le pointeur de cette carte
  • quelque chose de complètement différent. Peu importe la façon dont il est fait, c'est-à-dire que cela se fait (et que d'autres réponses ont souligné, utilisez Suppr [] avec NEW [] !!)

0 commentaires

5
votes

Si vous faites un type de tableau non-tableau:

T t* = new T[10];
// ...
delete [] t;


0 commentaires

3
votes

Ce n'est pas une question de mieux ni pire. Les deux sont des opérations avec le même objectif, 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:

  • Nouveau / Supprimer sont des mots-clés C ++ et ne sont pas disponibles dans la langue C
  • Nouveau / Supprimer est le type SAFE, tandis que MALLOC () / gratuit () ne sont pas. Cela signifie que les pointeurs retournés par MALLOC () et gratuit () sont void des pointeurs qui doivent être distribués au type correct.
  • Nouveau / Supprimer Supporte implicitement une allocation et une suppression de la matrice et de la suppression en utilisant le Nouveau [] et Suppr [] Syntaxe Utilisation de méta-données fournies par le compilateur, MALLOC () / free () Ne pas prendre en charge cette syntaxe
  • Application Nouveau / Supprimer à un type de classe t appellera respectivement le constructeur et le destructeur de t , MALLOC () / GRATUIT () N'appelez pas le constructeur et destructeur de T
  • malloc () retournera null en cas d'épuisement de la mémoire, nouveau lancera une exception

    Notez que pour empêcher la corruption de la mémoire, la mémoire allouée à l'aide de Nouveau doit être libérée à l'aide de Supprimer . La même chose pour la mémoire allouée à l'aide de MALLOC () , qui doit être libérée à l'aide de gratuit () . .


0 commentaires

3
votes

répondant spécifiquement à votre question, l'opérateur de suppression invoque le destructeur, où libre ne le fait pas; D'où la raison pour laquelle vous ne voulez pas mélanger malloc / gratuit avec de nouveaux / Supprimer.

Lorsque la bibliothèque du compilateur attrape la mémoire du tas, elle attrape un peu plus que vous demandez qui inclut l'espace pour la tenue de la maison, certaines métadonnées et si nécessaire, le rembourrage.

Dites que vous MALLOC 128 octets, ou neuf une matrice de huit objets de 16 octets. Le compilateur pourrait réellement saisir 256 octets, incluez un petit bloc de gestion du tas au début, enregistré qu'il vous a donné 128 mais saisit 256 et vous rendez-vous un décalage dans ce bloc de 256 quelque part après l'en-tête. Vous êtes assuré que de ce pointeur, vous avez 128 octets que vous pouvez utiliser, mais si vous allez au-delà de cela, vous pourriez avoir des problèmes.

Les opérateurs gratuits et de suppression sous la hotte prendront le pointeur que vous avez été remis, sauvegardez un décalage connu, lisez son bloc d'en-tête, et savez-le pour libérer 256 octets vers le tas.


0 commentaires