The output of the below code is 2500. It contains pointers. Can someone give a proper explanation of this? Why does it print as 2500? Does it come through the pointer declaration or is there another reason?
#include <stdio.h>
/* 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;
}
The reason you are getting weird output is undefined behavior. You are returning the address of automatic local variable which will no longer exist once function reach its end.
Although, the explanation for the output can be given in terms of stack frame of function call. Since the last call is for function g
and the argument passed to it is 2500
, the parameter x
of function g
is allocated on stack and 2500
is pushed to the stack. When this function return, this value popped from the stack (though the stack frame for g
is invalid after return to the caller) and it may return this 2500
from its stack frame.
In both of your functions, you try to return the address of a local variable in the function. Once the function finishes the execution and the control returns to the caller, the returned address becomes invalid (i.e., the variables go out of scope) and any attempt to make use of the returned value invokes undefined behavior.
If you have to return an address from a function and use it in the caller, you'll be needing a pointer which has been allocated memory through dynamic memory allocator functions, like malloc()
and family.
I think what happens can be explained using the stack. When calling the function f, stack behaves as follows. "ret" is the return address.
2| | 2| | 2| | 2| p |
1| | -> 1| | -> 1|ret| -> 1|ret|
0| | 0|100| 0|100| 0|100|
Now stack pointer is at 2, and that address (address of p) is returned and assigned to *x in main. When it returns from f, all stack values are popped, but actually what happens is just reducing the value of the stack pointer. Therefor the values pushed are still there. The again function g is called and stack is as follows.
2| p | 2| p | 2| p | 2| y |
1|ret | -> 1|ret | -> 1|ret | -> 1|ret |
0|100 | 0|2500| 0|2500| 0|2500|
Same as function f, address of p is returned and assigned to *y in main. But notice that it's also the same address as p, 2. Hence *x and *y in main both point to the same location. Function g set the values of that address to 2500, so both *x and *y prints 2500.
Hope this helps. :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With