why the second printf prints garbage value

天大地大妈咪最大 提交于 2019-12-10 11:38:50

问题


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

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!