问题
this is the source code
#include <stdio.h>
#include <stdlib.h>
int *fun();
int main()
{
int *j;
j=fun();
printf("%d\n",*j);
printf("%d\n",*j);
return 0;
}
int *fun()
{
int k=35;
return &k;
}
output-
35
1637778
the first printf() prints 35 which is the value of k but
In the main() the second printf prints a garbage value rather than printing 35.why?
回答1:
The problem here is the return from fun
is returning the address of a local variable. That address becomes invalid the moment the function returns. You are simply getting lucky on the first call to printf
.
Even though the local is technically destroyed when fun
returns the C runtime does nothing to actively destroy it. Hence your first use of *j
is working because the memory for the local hasn't been written over yet. The implementation of printf
though is likely over writing this simply by using its own locals in the method. Hence in the second use of *j
you're referring to whatever local printf
used and not k
.
In order to make this work you need to return an address that points to a value that lives longer than fun
. Typically in C this is achieved with malloc
int *fun() {
int* pValue = malloc(sizeof(int));
*pValue = 23;
return pValue;
}
Because the return of malloc
lives until you call free
this will be valid across multiple uses of printf
. The one catch is the calling function now has to tell the program when it is done with the retun of fun
. To do this call free
after the second call to printf
j=fun();
printf("%d\n",*j);
printf("%d\n",*j);
free(j);
回答2:
Program invokes undefined behavior. You can't return a pointer to an automatic local variable. The variable no longer exist once fun
returns. In this case the result you get, may be expected or unexpected.
Never return a pointer to an automatic local variable
回答3:
You are returning local value it is stored in stack. When you move out of function it gets erased. You getting undefined behaviour
.
In your case stack
not changed after function returning, so first time you getting correct value. This is not same in all time.
回答4:
Both are wrong, since you print a value that no longer exists: the memory to store int k
in the function is ok only while the function is executing; you can't return a reference (pointer) to it, since it will no longer reference anything meaningful.
The following, instead, would work:
int *fun()
{
static int k=35;
return &k;
}
The static keyword "says" that the memory must "survive" even if the function is not running, thus the pointer you return will be valid.
回答5:
As others already told, your program invokes undefined behavior.
That means, anything can happen where the behaviour is not defined.
In your case, the following happens: The address of the variable, sitting on the stack, is returned. After returning from the function, the next function call can - and will - reuse that space.
Between the function call erroneously returning this address and the call using the value, nothing happens - in your case. Be aware that even this might be different on systems where interrupts may occur, and as well on systems with signals being able to interrupt the normal program run.
The first printf()
call now uses the stack for its own purpose - maybe it is even the call itself which overwrites the old value. So the second printf()
call receives the value now written into that memory.
On undefined behaviour, anything may happen.
来源:https://stackoverflow.com/questions/20936394/why-the-second-printf-prints-garbage-value