“静态分配”堆栈中的变量?
我在阅读本文时看到:“本文假定您已经了解并理解GNU / Linux系统中的内存映射如何工作,特别是在堆栈中静态分配的内存与在堆。”
这使我感到困惑,因为我认为堆栈和堆是动态分配的,意味着只在必要时分配,并且在函数内声明为“静态”的全局变量和变量是静态分配的,意味着始终分配。
例如,如果我有
void f() {
int x = 1;
...
}
值1只能放在堆栈上,并且只有函数f()被调用时,堆栈指针才会增加。 同样,如果我有
void f() {
int x = malloc(1 * sizeof(int));
...
}
只有在调用f()时才会分配堆内存。 但是,如果我有“int x = 1;” 在程序的全局部分或“static int x = 1;” 在函数体内,任何时候我运行这个程序,该内存将被分配到值为1的数据部分。
我错了吗?
堆栈本身是静态分配的。 随着控制流程进入和离开其范围,堆栈中分配的变量会随之而来。
即使初始化语句位于函数体内部,静态变量也仅初始化一次。
检查维基百科示例:
#include <stdio.h>
void func() {
static int x = 0;
/* x is initialized only once across five calls of func() and
the variable will get incremented five
times after these calls. The final value of x will be 5. */
x++;
printf("%dn", x); // outputs the value of x
}
int main() { //int argc, char *argv[] inside the main is optional in the particular program
func(); // prints 1
func(); // prints 2
func(); // prints 3
func(); // prints 4
func(); // prints 5
return 0;
}
该堆栈基本上是一个大的静态分配数组,其中有一个从其开始处开始的可移动指针。 当你调用一个函数(从w / main开始)时,指针会移动(创建一个堆栈帧),并且堆栈帧中的空间被分割并提供给局部变量(有多少局部变量可以决定函数堆栈帧的大小将会)。 所以局部变量是动态的(它们只在你输入函数后才会出现),但是这个栈的大小是静态的。 如果你在它上面分配了一个超大型结构或者使用了太多的递归,那么你会走到最后,操作系统会让你失望 - 一种被称为stackoverflow的现象。 (The icon实际上说明了这一点 底部的灰色容器表示堆栈所在的静态数组。 橙色矩形是通过函数调用创建的框架。 就像正确的堆栈溢出一样,这些帧溢出容器和繁荣 - 你的程序已经死了。 框架上升的事实说明了堆栈的另一个特别之处 - 新框架的地址比旧堆栈的地址低,所以stackoverflow实际上发生在堆栈数组的开头,而不是堆栈的末尾(除非您将数组视为从他们最大的指数开始到0)。 )
堆栈以堆栈帧为单位进行分配。
而且,堆栈有助于存储函数参数和局部变量。
函数获得堆栈帧后,是的,在堆栈帧内,函数使用它的字节作为需要动态的。
像堆一样动态分配堆栈
如果你想像栈堆一样分配堆栈内存,那么你可以使用<alloca.h>
alloca()
,它比堆快,但在大多数情况下你不需要它,它有缺点,因此不会在一般情况下建议。
在不同的上下文中描述堆栈分配可能会使其更加清晰:
thread
的角度来看,(顺便说一下,每个进程默认创建1个线程作为主线程),堆栈的大小和分配在线程创建时分配(2Mb为IA-32,32Mb为IA -64,默认),你可以根据需要更改默认大小。 所以你可以说这是固定的,而且是静态的。 function
来看,当函数启动时,从线程的堆栈内存中为它分配堆栈帧,并在函数完成时堆栈帧消失。 local variable
的角度来看,动态地根据需要从函数的栈帧中分配变量。 所以,它应该被称为静态或动态,你决定。
链接地址: http://www.djcxy.com/p/82819.html上一篇: Are variables on the stack "statically allocated"?
下一篇: Where is allocated variable reference, in stack or in the heap?