Memory stick

On the stack, memory is reserved for main , which we call the frame stack for the main function.

When we call the Add function, memory is allocated over the stack. In the stack frame of the Add functions, a and b are local pointers, and c is an integer that calculates the sum and then returns the link. c is the local variable of the Add function.

Now that the Add function has completed, the memory space on the stack is also freed, so when we try to access this address in main with a pointer p , what we are trying to get is basically freed space. The compiler gives a warning, but why is it still printing the value 5 correctly?

The answer to this question may lie in the fact that the machine did not free the memory space, because it did not consider it necessary, since there were no more functions. But if we write another Hello function, then it should definitely free up space for the Add function in the call stack, but the program still prints

 Yay 5 

This is because, as in the heap, we need to assign a pointer to null after it is released, otherwise we can still access it? Is there something similar here?

 /* void Hello() { printf("Yay"); } */ int* Add(int *a,int *b) { int c=*a+*b; return &c; } int main() { int a=1,b=4; int *p=Add(&a,&b); // Hello(); printf("\t%d",*p); return 0; } 
+5
source share
5 answers

Assuming c is a local int variable, accessing c after calling the function is undefined-behavior and may produce the expected result or may do something unexpected.

Although C not required, it is usually implemented using the stack. For performance reasons, when a function returns, it leaves the stack area unchanged. This is why you see the value 5 , i.e. 1+4 . But you should never count on it.


When you use the second function, the behavior remains undefined, so you can get any output. In practice, if you define another variable in the second function and use it, the output may change.

  +-----------------+ .(local variables). |'''''''''''''''''| | | +----------------+ . PRINTF FUNCTION . | c = 42 | | | |''''''''''''''''| +-----------------+ | | | | . ADD FUNCTION . . HELLO FUNCTION . | | | | +----------------+ +-----------------+ | b = 4 | | b = 4 | |''''''''''''''''| |'''''''''''''''''| | a = 1 | | a = 1 | |''''''''''''''''| |'''''''''''''''''| | | | | . MAIN FUNCTION . . MAIN FUNCTION . | | | | +----------------+ +-----------------+ 

In the above diagram, I tried to visually imagine what the stack might look like when you are inside the Add function and the Hello function. You can see that Hello does not spoil the stack memory that was reserved for c in the Add function.

You can verify this by rewriting the Hello function as

 void Hello() { int i = 42; printf("Yay - %d\n", i); } 

Can print 42 in main .

+8
source

TL DR answer, this is undefined behavior. You cannot explain any conclusion of the above performance. Don't be surprised if he finishes printing your mobile number or zip code .:-)

After expiration, what happens to the location of the stack depends on the environment. If this is not required, the stack space allocated for c may not be reused and therefore you see the supposed correct output, but still it is undefined. Someday, in a different environment, you may see a different answer.

Mr. Mothit Jain answer gives a very detailed explanation of this.

+1
source

To fully understand this, I recommend that you study the assembly for your processor and see how your code compiles. At the moment, I think it can help if I say that returning from the function does not cause the memory deallocation function, it just adjusts the registers, and since you didn’t do anything between adding and printing to change the value in the "deallocated" stack, you get the number. Try calling a function that returns .. pfft i dunno 77 between them (but save it in a local variable!), And you will print another result. Learn the assembly though, to be the right programmer.

+1
source

The Hello function does not add anything new to the stack because it does not have automatic variables. Therefore, the memory location that c previously occupied did not change. Change Hello so that it changes memory and you change the value to p .

 void Hello(void) { //This will overwrite the memory previously containing '5' with '3`, the number //of characters output by the printf() function. int grub = printf("Yay"); } 
0
source

I think this is because you did not define a "stack variable" in the Hello function when I run the following program:

 #include <stdio.h> void Hello() { int tt = 100; int tt1 = 5000; printf("Yay"); } int* Add(int *a,int *b) { int c=*a+*b; return &c; } int main() { int a=1,b=4; int *p=Add(&a,&b); Hello(); printf("\t%d",*p); return 0; } 

It prints 5,000 on my Linux and 1 on my Mac. In any case, I think both of them are unexpected value.

0
source

Source: https://habr.com/ru/post/981047/


All Articles