2012-01-03 4 views
2

Possible en double:
Returning the address of local or temporary variable
Can a local variable's memory be accessed outside its scope?Revenant pointeur à une variable fonction locale

Je sais que je ne devrais pas retourner des pointeurs vers des variables de la fonction locale (variables de pile locale), car lorsque le retour de la fonction, les variables seront invalides et la pile sera nettoyée à moins que je n'ai rendu ces variables statiques ou les ai allouées sur le tas.

Le code suivant montre que:

const char* v1() { 
    return "ABC"; 
} 

const char* v2() { 
    string s = "DEF"; 
    return s.c_str(); 
} 

const char* v3() { 
    static string s = "JHI"; 
    return s.c_str(); 
} 

cout << v1() << endl; // Output: ABC 
cout << v2() << endl; // Output: garbage (♀ ╠╠╠╠╠╠╠╠) 
cout << v3() << endl; // Output: JHI 

Cependant, je suis retourné pointeur vers une variable de fonction locale primitive et je suis en mesure d'obtenir sa valeur même si elle n'est pas statique, comme le code suivant indique:

int i1() { 
    int i = 5; 
    return i; 
} 

int* i2() { 
    int i = 6; 
    return &i; 
} 

int* i3() { 
    static int i = 7; 
    return &i; 
} 

cout << i1() << endl; // Output: 5 
cout << *i2() << endl; // Output: 6 !! 
cout << *i3() << endl; // Output: 7 

Le compilateur me donne seulement un avertissement que je retourne l'adresse de la variable locale ou temporaire (Visual C++ 2008). Ce comportement est-il commun à tous les compilateurs et comment le compilateur me permet-il d'utiliser un pointeur vers une variable de fonction locale pour accéder à la valeur vers laquelle il pointe bien que la variable soit invalidée lorsque la fonction retourne?

+3

Sa valeur arrive à rester en mémoire au même endroit. Le fait que cela fonctionne est soit un accident, soit un résultat de votre compilation en mode "Debug". Je ne suis pas sûr de la question, vous savez déjà que vous ne devriez pas faire cela. Écoutez les avertissements que votre compilateur émet! –

Répondre

2

il peut être retiré de la pile car il est local mais la valeur restera jusqu'à ce qu'une autre l'écrase. C++ est une langue dangereuse vous pouvez faire beaucoup de choses étranges

2

vous renvoyez une adresse. Le retour d'une adresse est toujours valide. Mais dans votre cas, vous le dérérez également. C'est un comportement indéfini. Théoriquement, pour un comportement indéfini, tout peut arriver. Le compilateur est même autorisé à intégrer du code pour formater votre disque dur. Pratiquement, il va déréférencer l'adresse sans aucun contrôle. Si elle est toujours accessible, elle renverra la valeur à cette adresse sinon cela entraînera une violation d'accès.

Votre adresse est sur la pile, elle est donc toujours accessible. Selon les appels que vous avez faits entre, la valeur peut encore être là ou pas. Donc, dans les cas simples, vous récupérez la valeur, dans les cas plus complexes, vous ne le faites pas. Cela peut même fonctionner parfois et parfois non. Pour plus d'informations, vous devriez lire quelques informations sur la façon dont les appels de fonctions sont faits en assembleur pour comprendre ce que fait le compilateur sur la pile (paramètres, adresse de retour, placement de variables locales, nettoyage de pile en retour, conventions d'appel).

Questions connexes