7
votes

Pourquoi appelle-t-il gratuitement () sur un pointeur alloué à la corruption de la "nouvelle" cause?

Est-ce que cela fonctionne réellement sur certains compilateurs / machines, mais sur d'autres, il provoque des corruptions de tas et des accidents?

Quelqu'un a-t-il un aperçu de ce qui se passe sous les couvertures?


7 commentaires

Il demande pourquoi vous obtenez ce comportement, c'est simplement lui dire de ne pas le faire, cela n'aide pas sa compréhension de rien.


@bobdevil: D'accord, le comportement est indéfini par la norme C ++, ce qui signifie que les implémentations de langues ne ressentent aucun désir d'imposer un comportement raisonnable. Il n'y a pas de comportement traditionnel (autre que "ne fais pas ça!"), Il n'ya même pas de norme informelle. Empiriquement, le comportement semble varier. Par conséquent, vous ne pouvez pas compter sur un comportement particulier et aucun ingénieur de compilateur ne vous donnera aucune sympathie. C'est assez de raison pour dire "ne le fais pas!" Sans entrer dans une explication quant à la raison pour laquelle un comportement particulier se produit.


Stackoverflow.com/Questtions/240212/...


Oui, vous avez raison, standard ne garantit rien. Je suppose que je venais de réagir à la façon dont il a été répondu. Vous êtes un deuxième commentaire, alors que surtout une réplique en colère à mon commentaire, était beaucoup plus utile.


@bobdevil: Sauf que "c'est un comportement indéfini; ne le fais pas" est la bonne chose à dire. Créer des scénarios sur différents comportements possibles est principalement inutile et devrait être inutile.


Je me demande, si une référence de bibliothèque indique qu'une ressource créée par "Createxx" doit être publiée par "hrotexx", allez-vous toujours expérimenter ce qui se passerait si vous appelez "Destructyy" à la place? Pourquoi est-ce une question aussi populaire - presque aussi populaire que "quel est le résultat de a = ++ a; "?


@Unclebens Sa probablement parce que c'est souvent le cas que les pointeurs soient couplés à vide à travers de nombreux niveaux d'indirection et d'erreurs résultent de ne pas retrouver comment ils ont été alloués.


3 Réponses :


19
votes

C ++ souhaite appeler un destructeur sur l'objet lorsque vous utilisez Supprimer , mais le transmettant à gratuit ne permet pas que cela se produise. Si l'objet contenait d'autres objets, les destructeurs des objets ne seraient pas appelés non plus. Si l'objet avait des pointeurs dedans, ceux-ci ne seraient pas libérés.

Additionnellement C ++ 'S Nouveau et Supprimer pourrait réellement demander une plus grande quantité de mémoire de Malloc et utiliser le supplément pour la conservation du livre (comme stocker le Adresse de la fonction destructeur), et donc le pointeur que vous avez transmis à gratuit ne serait pas vraiment celui qui était malloc ed.


0 commentaires

2
votes

La norme dit que vous devez correspondre parfaitement à la fonction d'allocation / distribution de translocation ( nouveau - Supprimer , nouveau [] - Supprimer [] , malloc - gratuit ). Théoriquement, il est tout à fait possible que certains compilateurs implémentent opérateur nouveau () comme simple malloc () , donc cela ne causerait pas de crash, mais "seulement" sauter le appel destructeurs (qui est mauvais en soi). Cependant, opérateur [] peut stocker le nombre d'éléments dans le morceau de mémoire alloué auquel cas, l'adresse renvoyée par Nouveau [] points à l'intérieur du bloc attribué par MALLOC () (pas au début), ce qui signifie que vous ne pouvez pas le libérer avec gratuit () .


0 commentaires

2
votes

Le nouvel opérateur est également surchargé. Si quelqu'un a écrit un nouvel opérateur qui faisait quelque chose de très différent, dites-vous à attraper des pointeurs d'une piscine mémoire, appelant gratuitement sur ces pointeurs pourrait être très dangereux.


0 commentaires