2010-10-22 37 views
2
const char *Greet(const char *c) { 
    string name; 
    if(c) 
     name = c; 
    if (name.empty()) 
     return "Hello, Unknown"; 
    return name.c_str(); 
} 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    cout << Greet(0) << '\t' << Greet("Hello, World") << endl; 
    return 0; 
} 

Je vois 2 bogues avec le code ci-dessus.Retour d'une fonction

  1. Renvoyer c_str d'un objet chaîne défini localement pour la fonction. La chaîne est détruite lorsque la fonction retourne et c_str() pointe clairement vers une mémoire qui est désaffectée.

  2. Retour "Bonjour, Inconnu" à partir de la fonction. C'est encore un tableau de const consts alloués dans la pile qui devrait être désaffecté aussi bien quand la fonction retourne. Cependant, ce n'est pas le cas et je suppose que c'est à cause de l'optimisation de la valeur de retour.

Est-ce que ma compréhension ci-dessus est correcte? PS: J'ai testé le code ci-dessus avec gcc et MSVC10. GCC exécute le code ci-dessus correctement et ne génère aucune erreur d'exécution ou comportement non défini à la fois pour l'objet chaîne et pour la chaîne constante. MSVC10 affiche des données parasites pour l'objet chaîne mais imprime correctement la chaîne constante.

+0

Eh bien, techniquement, le comportement de GCC pour 'Greet (" Hello, World ")' _is_ undefined – AlcubierreDrive

Répondre

11

Le numéro 1 est correct. Le pointeur renvoyé par c_str() est invalidé lorsque name est détruit. Le déréférencement du pointeur après name entraîne un comportement indéfini. Dans vos tests, sous gcc, apparaît pour fonctionner; sous Visual C++ il imprime des déchets. Tous les résultats sont possibles lorsque le comportement est indéfini.

Le numéro 2 est incorrect. "Hello, Unknown" est un littéral de chaîne. Les littéraux de chaîne ont une durée de stockage statique (ils existent depuis le démarrage du programme jusqu'à sa fin.) Vous renvoyez un pointeur vers ce littéral de chaîne, et ce pointeur est valide même après le retour de la fonction

1

Les littéraux de chaîne ont un stockage statique , donc ne sont pas désalloués à la fin de la fonction