内存分配栈 [英] Memory allocation stack
问题描述
在堆栈中,为main
保留了内存,我们将其称为main
函数的堆栈帧.
In the stack, memory is reserved for main
which we call stack frame for the main
function.
当我们调用Add
函数时,内存保留在堆栈的顶部.在Add
函数堆栈框架中,a
和b
是局部指针,而c
是一个整数,用于计算总和,然后返回引用. c
是Add
函数的局部变量.
When we call the Add
function, memory is reserved on top of the stack. In the Add
function stack frame, a
and b
are local pointers and c
is an integer which calculates the sum and then we return the reference. c
is a local variable of Add
function.
现在,当Add
函数执行完成时,堆栈中的内存空间也会被释放,因此,当我们尝试使用指针p
访问main
中的该地址时,我们试图访问的基本上是一个释放空间.编译器发出警告,但是为什么它仍然可以正确打印5值?
Now when the Add
function execution is completed the memory space in the stack is also deallocated so when we try to access this address in the main
with pointer p
, what we are trying to access is basically a deallocated space. The compiler gives a warning but why does it still print the value 5 correctly?
答案可能是机器没有释放内存空间,因为没有更多的功能,所以它认为没有必要.但是,如果我们编写另一个函数Hello
,那么它肯定应该在调用堆栈中为Add
函数分配空间,但是程序仍会打印
The answer to that may be that the machine didn't deallocate the memory space as it didn't deem it necessary as there were not any more functions. But if we write another function Hello
then it should definitely deallocate the space for Add
function in the call stack but the program still prints
Yay 5
是因为像在堆中一样,我们需要在释放null
之后分配一个指向null
的指针,否则我们仍然可以访问它?这里有类似的东西吗?
Is it because like in heap we need to assign a pointer to null
after freeing it or else we can still access it? Is something like that related 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;
}
推荐答案
假定c
是局部int
变量,在函数调用为undefined-behavior
后访问c
,可能会打印预期的结果,或者可能执行意外的操作
Assuming c
is local int
variable, accessing c
after function call is undefined-behavior
and may print expected result, or may do something unexpected.
尽管C
不是强制性的,但通常使用堆栈来实现.出于性能原因,当函数返回时,它将使堆栈区域保持不变.这就是为什么您看到值5
即1+4
的原因.但是您永远不要指望这一点.
Though C
doesn't mandate, but typically it is implemented using stack. For performance reasons, when a function returns, it leaves the stack area unchanged. That is the reason why you are seeing the value 5
i.e. 1+4
. But you should never count on this.
使用第二个函数时,行为仍未定义,因此您可以获得任何输出.实际上,如果您在第二个函数中定义另一个变量并使用它,则输出可能会更改.
When you use the second function, behavior still remains undefined so you can get any output. In practice if you define another variable in 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 .
| | | |
+----------------+ +-----------------+
在上图中,我试图直观地表示当您在Add
函数和Hello
函数内部时,堆栈的外观.您可以看到Hello
并没有弄乱Add
函数中为c
保留的堆栈内存.
In above diagram, I tried to visually represent how the stack might stack look when you are inside Add
function and Hello
function. You can see that Hello
is not messing up with the stack memory that was reserved for c
in Add
function.
您可以通过将Hello
函数重写为
You can verify this by rewriting the Hello
function as
void Hello()
{
int i = 42;
printf("Yay - %d\n", i);
}
可以在main
中打印42
.
这篇关于内存分配栈的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!