Prithvi Raj
Prithvi Raj

Reputation: 31

Call Stack - while a function returns reference of local variable to the calling function which is followed by the call to another function

#include<stdio.h>

int *fun();
int main()    
{
   int *ptr;
   ptr=fun();
   printf("%d",*ptr);
   printf("%d",*ptr);
}
int * fun()
{
   int k=4;//If auto then cannot print it two times.....stack will be changed
   return(&k);
}

O/P: 4
    -2

Calling printf() for the first time prints the correct value.

Calling any function (even printf( ) ) immediately after the call to fun( ). This time printf( ) prints a garbage value. Why does this happen?Why do we not get a garbage value during the first print statement itself????

Upvotes: 0

Views: 229

Answers (3)

AnT stands with Russia
AnT stands with Russia

Reputation: 320631

Why does it surprise you? The behavior is undefined, but there's nothing unusual in observing what you observed.

All variables live somewhere in memory. When a variable gets formally destroyed (like local variables when function exits) the memory it used to occupy still exists and, most likely, still holds the last value that was written to it. That memory in now officially free, but it will continue to hold that last value until some other code reuses that memory for other purposes and overwrites it.

This is what you observe in your experiment. Even though the variable kno longer exists, pointer ptr still points to its former location. And that former location still happens to hold the last value of k, which is 4.

The very first printf "successfully" receives a copy of that value for printing. And that very first printf is actually the one that reuses the old memory location and overwrites the former value of k. All further attempts to dereference ptr will show that 4 is no longer there, which is why your second printf prints something else.

Upvotes: 2

dejavu
dejavu

Reputation: 3254

Variable k is local to fun(), means it will be destroyed when the function returns. This is a very bad coding technique and will always lead to problem.

And the reason why the first printf returns the correct value:

First of all it might or might not return the value. The thing is suppose k is written somewhere on stack memory. First time when the function returns printf might get the correct value because that part of memory might exist for a while. But this is not guaranteed.

Upvotes: 1

Eric Postpischil
Eric Postpischil

Reputation: 223264

This is not behavior you can rely on; it may and likely will differ on different systems, even different versions of the compiler or different compiler switches.

Given that, what is likely happening is this: fun returns a pointer to where it stored k. That part of the stack is no longer reliable, because the function that allocated it has exited. Nonetheless, nobody has written over it yet, so the 4 is still where it was written. Then main prepares to call printf. To do so, it gets the first argument, *ptr. To do this, it loads from the place ptr points, which is the (former) address of k, so the load gets the 4 that is there. This 4 is stored in a register or stack location to be passed to printf. Then the address of the format string, "%d", is stored to be passed to printf. Then printf is called. At this point, printf uses a great deal of stack and writes new data where k used to be. However, the 4 that was passed as an argument is in a safe place, where arguments to printf should be, so printf prints it. Then printf returns. Then the main routine prepares to call printf again. This time, when it loads from where ptr points, the 4 is no longer there; it is some value that was written during the first call to printf. So that value is what is passed to printf and is what is printed.

Never write code that uses this behavior. It is not reliable, and it is not proper code.

Upvotes: 2

Related Questions