2010-12-07 63 views
4

Code 1:Quand la mémoire, pointée par (char *) en tant que paramètre de fonction est-elle supprimée?

void foo(char * text) {} 

foo("Test"); 

pour autant que je comprends, cela se produira:

  • mémoire est allouée pour "Test"

  • pointeur

    est créé et sa valeur est copyed à (char * texte pointeur), donc (char * texte) pointe vers l'endroit en mémoire, où "Test" est (mieux vaut dire, sur le premier caractère de "Test")

  • après que la fonction est terminée, il détruit le pointeur (texte char *), pointant vers le début de "Test", ne crée-t-il pas une fuite de mémoire?

  • et la question est, quand la « Test » est supprimé, lorsque la fonction ne détruit que le pointeur

est pas mieux à faire grincer. comme ça? :

char * _text = "Test"; 
foo(_text); 
delete[] _text; 

Répondre

3

Vous pouvez considérer les littéraux de chaîne comme faisant partie du code. Ils ne sont pas alloués dynamiquement, ils ont ce qu'on appelle la "durée de stockage statique", ce qui signifie qu'ils existent pour la durée du programme, et qu'ils n'ont pas besoin d'être libérés (en effet, ils ne doivent pas être libérés).

Il est toujours faux de delete[] quelque chose qui n'a pas été créé avec new[], donc votre deuxième fragment de code a un comportement indéfini.

+0

quand je le fais // char * _text = "Test"; foo (_text); // le "Test" sera-t-il également créé en stockage statique? // donc je n'ai pas besoin d'appeler delete? ne serait-il pas préférable d'utiliser const char * _text = "Test"? pourquoi puis-je le passer comme un char *, alors que je suis un const const * –

+0

@Peter: il y a une conversion désapprouvée de la chaîne littérale à non-const 'char *'. Il est là pour prendre en charge le code C hérité avant l'invention de 'const' (en notation d'échecs, on écrirait (?!) Ici). L'utiliser * ne permet pas de modifier les données vers lesquelles il pointe, cela a juste le même effet que de supprimer const d'un pointeur avec un 'const_cast'. Si vous voulez quelque chose que vous pouvez modifier, vous pouvez écrire 'char text [] =" Test ";' - cela place un tableau sur la pile et copie la chaîne littérale dans ce tableau, ainsi vous pouvez modifier la copie. Comme toute autre variable automatique, sa durée de vie est sa portée. –

2

"Test" est un littéral de chaîne qui a une durée de stockage statique. Il ne sera pas supprimé tant que le programme ne fonctionnera pas. Et vous ne devriez pas le supprimer par vous-même.

+0

donc c'est bon. comme la fuite de la mémoire? quand je fais comme: foo ("Test"); foo ("Test"); cela va-t-il créer 2 constantes? –

+0

Ce n'est pas une fuite de mémoire.Il sera supprimé automatiquement lorsque le programme quittera (juste après le retour de la fonction 'main'). –

+0

La définition de l'implémentation indique si tous les littéraux de chaîne sont distincts (c'est-à-dire stockés dans des objets non chevauchants). Donc vous ne devriez pas compter sur 'foo (" Test "); foo ("Test"); 'appellera' foo' avec la même valeur de pointeur. –

0

En fait, il n'est pas supprimé.

Cette chaîne est allouée dans le segment de données et l'appel à foo("Test") pousse juste sur la pile le pointeur vers cette chaîne, sans "copier" comme vous le dites.

Il n'y a pas de fuite de mémoire car la chaîne fait partie du fichier binaire final et elle sera toujours là, dans une section du binaire qui est juste pour ce genre de choses (constantes et ainsi de suite).

Il arrive que la chaîne elle-même (les octets de "Test") soit placée dans un segment de données dans une section en lecture seule tandis que le pointeur (par exemple char *_test = "Test") est stocké dans une section de lecture-écriture. cela dépend de la façon dont le pointeur est initialisé et utilisé). Vous êtes autorisé à modifier le pointeur mais cela ne supprimera pas la chaîne du segment de données.

0

Les valeurs codées en dur dans C sont réellement compilées dans le binaire et ne sont donc pas allouées. Plus correctement, ils apparaissent dans la section "données" de l'exécutable et vivent aussi longtemps que le programme.

De même, les pointeurs ne sont pas "détruits". Rappelez-vous que les pointeurs ne sont que des adresses à la mémoire qui peuvent être n'importe où (pile/tas) mais pointeurs a pas d'objets.

+0

Les pointeurs sont des objets dans le seul sens que C++ définit "objet", bien que cette définition ne soit pas en accord avec la définition OOP de "objet". C'est un peu discutable s'ils sont détruits, puisque leur destruction n'a aucun effet, mais ils ont une durée de vie comme n'importe quel autre objet. –

+0

@Steve: Un pointeur tel que '& var' n'est pas un objet. Un pointeur * variable *, cependant, est. – fredoverflow

+0

@FredOverflow: bon nitpicking, oui, peut-être que j'aurais dû dire "pointeurs * peuvent être * objets" etc. '& var' est bien sûr une valeur. De même, 'int i;', 'i' est un objet mais' -i' est un rvalue. –