Maison >développement back-end >C++ >Lors du renvoi de la référence d'une variable locale, renvoie-t-elle la valeur ou l'adresse (et pourquoi est-ce dangereux) ?

Lors du renvoi de la référence d'une variable locale, renvoie-t-elle la valeur ou l'adresse (et pourquoi est-ce dangereux) ?

Mary-Kate Olsen
Mary-Kate Olsenoriginal
2024-12-20 02:05:10447parcourir

When Returning a Local Variable's Reference, Does It Return the Value or the Address (And Why Is This Dangerous)?

Énigme du référencement des variables locales : valeur ou adresse renvoyée ?

De nombreux programmeurs peuvent supposer que le renvoi de références à des variables locales ou temporaires dans des fonctions est erroné , entraînant un comportement indéfini. Cependant, dans certaines situations, cela peut étonnamment réussir et modifier la valeur de la variable. Étudions ce phénomène avec un exemple de code illustratif :

#include <iostream>

int& foo() {
    int i = 6;
    std::cout << &i << std::endl; // Prints the address of i before return
    return i;
}

int main() {
    int i = foo();
    std::cout << i << std::endl; // Prints the value
    std::cout << &i << std::endl; // Prints the address of i after return
}

Si nous exécutons ce code, nous observons un comportement curieux :

  1. L'adresse de la variable locale i dans foo() est imprimé avant de revenir, indiquant son existence dans le cadre de la pile.
  2. Bien que je sois une variable locale dans foo(), sa valeur est modifiée avec succès lorsque nous attribuons la valeur de retour à une variable dans main().
  3. L'adresse de i dans main() reste la même avant et après le retour, ce qui suggère que la variable réside toujours dans la mémoire de la pile.

Expliquer l'occurrence

Ce comportement déroutant peut être attribué à une bizarrerie dans la façon dont les cadres de pile sont gérés dans de nombreuses implémentations. Lors du retour d'une fonction, le cadre de pile n'est initialement pas immédiatement effacé.

Dans cet exemple, le type de retour est int&, ce qui signifie que la fonction renvoie une référence à l'adresse de i. L'affectation int i = foo(); in main() stocke l'adresse de i dans foo() dans la variable i dans main().

Simultanément, l'instruction de retour dans foo() ne libère pas immédiatement le cadre de pile. En conséquence, la variable i existe toujours dans la mémoire de la pile, alors qu'elle aurait dû être détruite. Cela permet à i d'être modifié via sa référence après son retour.

Précautions et implications

Bien que ce comportement puisse sembler pratique, il est extrêmement dangereux et peu fiable. S'appuyer sur la destruction retardée du cadre de pile est une recette pour un comportement indéfini.

Dans un code bien défini, vous devez vous assurer que les variables locales restent dans la portée de leur fonction de définition et sont rapidement détruites à la fin de celle-ci. Ne pas le faire peut entraîner des conséquences et des erreurs imprévisibles.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn