7
votes

const char * 's en C ++

Comment les expressions de chaîne dans C ++ fonctionnent-elles?

considéger: xxx

où et comment est l'expression "hey" stockée et pourquoi est-ce une défaut de segmentation quand je tente Pour la supprimer?


2 commentaires

Ce code est un bug. Vous ne pouvez pas supprimer un littéral.


Je pense que le questionneur comprend que beaucoup, Pavel. La question demande pourquoi .


9 Réponses :


4
votes

Vous ne pouvez pas supprimer les ressources statiques: celles-ci sont en lecture seule.


0 commentaires

20
votes

où il est stocké est laissé au compilateur pour décider dans cet étui (un peu spécial). Cependant, cela ne compte pas vraiment pour vous - si vous n'allouez pas de mémoire avec nouveau , ce n'est pas très agréable d'essayer de le réactiver avec Supprimer . Vous ne pouvez pas Supprimer la mémoire alloué dans la manière dont vous l'avez alloué.

Si vous souhaitez contrôler la répartition de cette ressource, vous devez utiliser un std :: string ou allouer un tampon à l'aide de MALLOC () . .


4 commentaires

Oh ... donc il n'est pas très recommandé d'utiliser des pointeurs sur Cons-Car Data, je suppose


@Pyjong: Vous êtes libre d'utiliser un pointeur pour référence à Const Char Data, n'essayez tout simplement pas de supprimer la mémoire référencée par le pointeur.


@Nick, j'ajouterais aussi que si vous allouez avec MALLOC , vous devez également vous assurer de libérer avec gratuit .


@Nick Meyer: Bon point. Cela semblait au-delà de la portée de la discussion actuelle .. :-)



1
votes

Vous ne pouvez pas supprimer des données constantes. Vous feriez seulement appeler Suppr [] TMP si vous aviez déjà appelé Nouveau Char [Stringsize] .


0 commentaires

16
votes

Lorsque vous affectez un constr * pointeur sur une chaîne constante comme "hey" dans l'exemple, la séquence hey \ 0 est stocké comme une variable statique à l'intérieur du binaire lui-même. Il ne peut pas être supprimé et ne doit pas être manipulé. Selon le système d'architecture / d'exploitation, il peut segfault lors de la manipulation .

Si vous deviez faire const caractère [] TMP = "hey" , les données seraient stockées sur la pile et peuvent être manipulées (mais non supprimées, comme il sera libéré une fois que le Stack Efface: lorsque la fonction renvoie).

Ne pas Supprimer [] Tout ce qui n'est pas Nouveau [] 'd.


0 commentaires

1
votes

Vous n'avez pas appelé nouveau sur la chaîne. C'est une fuite de mémoire potentielle de toute façon, pour chaque Nouveau Il existe un Supprimer , de même pour MALLOC et gratuit . Vous avez supprimé une référence de mémoire à un pointeur que simple est une gamme statique de caractères, au sens du mot.

J'espère que cela aide, Meilleures salutations, Tom.


0 commentaires

4
votes

Que se passe-t-il est.

"hé" signifie mettre de la chaîne "hey" dans une image binaire quelque part et donnez-moi une adresse de celui-ci , qui est la valeur de l'expression ("hey") . Il a du type de caractère *. À cette adresse, vous avez 4 octets. 'H', 'E', 'Y', et 0 (0 est appelé Terminator NULL conventionnel. (Rien à voir avec le terminateur de films) C'est la manière dont les littéraux de chaînes fonctionnent dans c.

Vous pouvez transmettre ce littéral comme tel: "une adresse d'une chaîne".

Vous ne pouvez pas le supprimer.

Lorsque vous construisez STD :: String ("Hey"), il prend cette chaîne pointue et la copie ailleurs - dans une mémoire nouvellement attribuée.


0 commentaires

10
votes

Le "hey" est un littéral à chaîne et est stocké dans le segment de données exécutable , qui est mappé dans la mémoire du processus au moment de la charge. La partie particulière dans laquelle les littéraux vivent sont mappés en lecture seule . Voici un extrait de l'assemblée produite à partir de votre code avec g ++ -s : xxx

de sorte que les données sont effectivement lecture seule , et Essayez de le manipuler avec Supprimer conduit à Segfault.


0 commentaires

0
votes

la chaîne "hey" a son espace pré-alloué dans le cadre du programme, il apparaît donc simplement lorsque le programme commence et disparaît lorsque le programme se termine.

Si vous voulez voir Un programme qui alloue la mémoire, l'utilise, puis le supprime, puis examinez ceci: xxx

remarque comment je suis arrivé à supprimer le nouveau d Mémoire en utilisant TMP . J'aurais pu faire ceci: xxx

Peu importe que, à la fin, nous indiquons la mémoire nouvelle d avec Hey ou TMP , aussi longtemps que nous le supprimons correctement pour éviter les fuites de mémoire.


0 commentaires

5
votes

const char * tmp = "hé";

"hey" est stocké dans un Zone en lecture seule du segment de données . Lorsque l'application démarre "hey" sera mappée sur la page de mémoire en lecture seule. xxx

Supprimer Accédez et modifie certaines métadonnées d'allocation. , Mais "hey" dans la page de mémoire en lecture seule.

changement de valeur en lecture seule n'est pas autorisé, Un défaut de segmentation est donc arrivé .


0 commentaires