La sortie du code ci-dessous est 2500. Il contient des pointeurs. Quelqu’un peut-il donner une explication appropriée de cela? Pourquoi est-il imprimé en tant que 2500? Cela passe-t-il par la déclaration du pointeur ou existe-t-il une autre raison?
#include /* Two functions include and they are operated by main function */ int *f(int x) { /* Creates an variable */ int p; p = x; return &p; } /* Here the initialization of the function g */ int *g(int x) { /* Creates an variable */ int y; y = x; return &y; } /* This creates two pointers called x and y */ int main() { int *x, *y; /* Here call the functions f and g */ x = f(100); /* Here call the function g */ y = g(2500); /* How does it print 2500? */ /* print the value of x */ printf("%d \n", *x); return 0; }
La raison pour laquelle vous obtenez une sortie étrange est un comportement indéfini. Vous retournez l’adresse de la variable locale automatique qui n’existera plus une fois que la fonction aura atteint sa fin.
Bien que l’explication de la sortie puisse être donnée en termes de cadre de stack d’appel de fonction. Comme le dernier appel concerne la fonction g
et que l’argument qui lui est transmis est 2500
, le paramètre x
de la fonction g
est alloué sur la stack et 2500
est envoyé à la stack. Lorsque cette fonction est renvoyée, cette valeur est extraite de la stack (bien que le cadre de la stack pour g
soit invalide après son retour à l’appelant) et il peut renvoyer cette valeur 2500
partir de son cadre de la stack.
Dans vos deux fonctions, vous essayez de renvoyer l’adresse d’une variable locale dans la fonction. Une fois que la fonction a terminé l’exécution et que le contrôle est retourné à l’appelant, l’adresse renvoyée devient invalide (c’est-à-dire que les variables sortent de la scope) et toute tentative d’utilisation de la valeur renvoyée appelle un comportement indéfini .
Si vous devez renvoyer une adresse d’une fonction et l’utiliser dans l’appelant, vous aurez besoin d’un pointeur qui a été alloué en mémoire via des fonctions d’allocation de mémoire dynamic, telles que malloc()
et family.
Je pense que ce qui se passe peut être expliqué en utilisant la stack. Lors de l’appel de la fonction f, la stack se comporte comme suit. “ret” est l’adresse de retour.
2| | 2| | 2| | 2| p | 1| | -> 1| | -> 1|ret| -> 1|ret| 0| | 0|100| 0|100| 0|100|
Maintenant, le pointeur de stack est à 2, et cette adresse (adresse de p) est renvoyée et atsortingbuée à * x dans main. Quand il retourne à partir de f, toutes les valeurs de stack sont sautées, mais en réalité, il ne fait que réduire la valeur du pointeur de stack. Par conséquent, les valeurs mises en avant sont toujours là. La fonction à nouveau g est appelée et la stack est comme suit.
2| p | 2| p | 2| p | 2| y | 1|ret | -> 1|ret | -> 1|ret | -> 1|ret | 0|100 | 0|2500| 0|2500| 0|2500|
Identique à la fonction f, l’adresse de p est renvoyée et affectée à * y dans main. Mais notez que c’est aussi la même adresse que p, 2. Par conséquent, * x et * y dans Main indiquent le même emplacement. La fonction g définit les valeurs de cette adresse sur 2500. Ainsi, * x et * y impriment 2500.
J’espère que cela t’aides. 🙂