Reputation: 247
#include<stdio.h>
int * fun(int a1,int b)
{
int a[2];
a[0]=a1;
a[1]=b;
return a;
}
int main()
{
int *r=fun(3,5);
printf("%d\n",*r);
printf("%d\n",*r);
}
Output after running the code:
3
-1073855580
I understand that a[2] is local to fun() but why value is getting changed of same pointer?
Upvotes: 0
Views: 134
Reputation: 1109
When you compile you code with the following command:
$ gcc -Wall yourProgram.c
It will yield a warning, which says.
In function ‘fun’:
warning: function returns address of local variable
When r
is dereferenced in first printf
statement, it's okay as the memory is preserved. However, the second printf
statement overwrites the stack and so we get an undesired result.
Upvotes: 1
Reputation: 48795
The variable a is indeed local to fun. When you return from that function, the stack is popped. The memory itself remains unchanged (for the moment). When you dereference r the first time, the memory is what you'd expect it to be. And since the dereference happens before the call to printf, nothing bad happens. When printf executes, it modifies the stack and the value is wiped out. The second time through you're seeing whatever value happened to be put there by printf the first time through.
The order of events for a "normal" calling convention (I know, I know -- no such thing):
r
(the first time through, this is what it should be)If you change int a[2];
to static int a[2];
this will alleviate the problem.
Upvotes: 7
Reputation: 882156
Because r
points to a location on the stack that is likely to be overwritten by a function call.
In this case, it's the first call to printf
itself which is changing that location.
In detail, the return from fun
has that particular location being preserved simply because nothing has overwritten it yet.
The *r
is then evaluated (as 3) and passed to printf
to be printed. The actual call to printf
changes the contents of that location (since it uses the memory for its own stack frame), but the value has already been extracted at that point so it's safe.
On the subsequent call, *r
has the different value, changed by the first call. That's why it's different in this case.
Of course, this is just the likely explanation. In reality, anything could be happening since what you've coded up there is undefined behaviour. Once you do that, all bets are off.
Upvotes: 2
Reputation: 109219
As you've mentioned, a[2]
is local to fun()
; meaning it is created on the stack right before the code within fun()
starts executing. When fun
exits the stack is popped, meaning it is unwound so that the stack pointer is pointing to where it was before fun
started executing.
The compiler is now free to stick whatever it wants into those locations that were unwound. So, it is possible that the first location of a
was skipped for a variety of reasons. Maybe it now represents an uninitialized variable. Maybe it was for memory alignment of another variable. Simple answer is, by returning a pointer to a local variable from a function, and then de-referencing that pointer, you're invoking undefined behavior and anything can happen, including demons flying out of your nose.
Upvotes: 1
Reputation: 31471
Because printf is using the stack location and changes it after printing the first value.
Upvotes: 0