The scope of local function variables in C

I heard about the following scenario when I started programming in C.

" When trying to access from outside, the local function variable will result in an error (or garbage value). Since the stack is cleared when we return from the function "

But my example below code prints the value 50. I am compiling the code with the latest GCC compiler.

#include <stdio.h> int * left(); int main() { int *p=left(); printf("%d\n",*p); return 0; } int * left() { int i=50; return &i; } 

Light me up on this issue.

Can I find out the behavior in C ++? This is similar to c ..

+4
source share
8 answers

Change it to add a second call to printf , and you will see a different value the first time. Compile it with optimizations enabled, and you will see a different set of values. Do something with a value, and you go to undefined territory, which means that the compiler can call daemons through your nasal passages.

On my system, I see 50 , and then 0 ; with optimizations I see 0 and then 32767 .

If you create a local static variable, you can return its address, since it will become like a global one (but remember that there is only one instance).

When the function returns, the local memory that it used on the stack is now considered an "unused" program, since the stack no longer reaches this maximum. However, as a rule, values ​​still exist, since there is no need to urgently clean them. The memory also still belongs to the program, since there is no point in returning several bytes at a time to the memory operating system. So, for your specific example, in the conditions in which you compiled it, the memory that it still points to contains a value of 50 . Officially, however, the value of *p is undefined, and attempts to use it lead to undefined behavior.

One existential C language crisis is how, on the one hand, it says nothing about the stack and the various bits of hexadecimal sediment that make up the current process; on the other hand, you need to understand them in order to protect yourself from crashes, buffer overflows and undefined behavior. Just remember that you are lucky that the GCC gives a warning for this.

+7
source

The variable "i" is created on the stack, and when the "left" function is returned, the stack is cleared. When I say that it is cleared, it means that the address used by the variable "i" is marked as free for reuse. Until any other part of the code uses the same address, the value will remain unchanged. In your case, just luck gives the desired results. If you call several functions after a call to the "left", I am sure that you will get the wrong results.

+12
source

C standard behavior is undefined, not garbage values. Thus, it is possible, and possibly the probability, that the value will remain unchanged. This is not guaranteed by any means.

It works by luck / chance / accident and nothing else. Do not rely on this behavior because it will come back to bite you.

+6
source

Look at this modified example, where it clearly shows that something is happening between:

 int *p=left(); // right here printf("%d\n",*p); 

You get a damaged stack easily. The idea is that you do not own this place, someone else can use it!

 int main() { int *p=left(); right(); // Look here! printf("%d\n",*p); // prints -50 instead of 50 return 0; } ... int * right() { int i=-50; return &i; } 
+3
source

The accident is working. The memory location pointed to by p still contains an integer value of 50 when printf() called. But calling any function inside main() between left() and printf() will overwrite it.

For example, I do not know what will happen in your implementation if you change your printf() call to:

 printf("abs(%d) = %d ???\n", *p, abs(*p)); 

Do not do this!

+2
source

You mean an object outside of its life (area left() ). This leads to undefined behavior - I would suggest that you still get 50, because nothing has overwritten the area in which i was not there.

+2
source

As for the C standard, the value is undefined.

In fact, until nothing is pushed onto the stack before the return value is returned, it will work, but the next time the function is called, the return address and the new stack stack will be pushed onto the stack and can overwrite the reference value .

This is not considered acceptable encoding (due to the nature of undefined).

+2
source

Undefined. i destroyed when left() exits. You have the garbage address in p . The compiler has not yet destroyed i .

+1
source

All Articles