运行时才可以确定栈空间大小的就要在运行时分配,如:int n = srand()%16; int buf[n];。
这里,我们主要关注下运行时栈空间分配,因为它和libmill协程栈的分配、组织有关系。先看这里的示例,int n = srand()%16; int buf[n]; ,这里数组的栈空间如何分配呢?这里的变量n的值只有在程序运行时才可以确定,所以这里的 int buf[n]; 肯定是在运行时动态分配栈空间的,我来解释下。
以如下源程序为例,代码很简单,运行时获取一个随机数n,用来作为动态创建数组的大小。
file: main.c
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
int n = rand();
int buf[n*100];
buf[0] = 1;
buf[n*100-1] = 0;
return 0;
}
运行命令gcc -g -O0 -o main main.c,然后运行`objdump -dS main`得到如下反汇编后的指令,如果读者有汇编基础的话,很容易就看懂了。前面我们也有提及,分配栈帧时通常通过对寄存器rsp的调整来实现,因为栈是从高地址向低地址方向增长的,所以对栈的分配动作其实是sub指令对rsp寄存器做减法操作,重点关注虚线“---”标注的部分就可以了。
alloca - allocate memory that is automatically freed
SYNOPSIS
#include <alloca.h>
void *alloca(size_t size);
DESCRIPTION
The alloca() function allocates size bytes of space in the stack frame
of the caller. This temporary space is automatically freed when the
function that called alloca() returns to its caller.
RETURN VALUE
The alloca() function returns a pointer to the beginning of the allocated
space. If the allocation causes stack overflow, program behavior is
undefined.
CONFORMING TO
This function is not in POSIX.1-2001.
There is evidence that the alloca() function appeared in 32V, PWB, PWB.2,
3BSD, and 4BSD. There is a man page for it in 4.3BSD.
Linux uses the GNU version.
NOTES
The alloca() function is machine- and compiler-dependent. For certain
applications, its use can improve efficiency compared to the use of malloc(3)
plus free(3). In certain cases, it can also simplify memory deallocation
in applications that use longjmp(3) or siglongjmp(3). Otherwise, its use
is discouraged.
Because the space allocated by alloca() is allocated within the stack frame,
that space is automatically freed if the function return is jumped over by
a call to longjmp(3) or siglongjmp(3).
Do not attempt to free(3) space allocated by alloca()!
...
BUGS
There is no error indication if the stack frame cannot be extended.
(However, after a failed allocation, the program is likely to receive
a SIGSEGV signal if it attempts to access the unallocated space.)
On many systems alloca() cannot be used inside the list of arguments
of a function call, because the stack space reserved by alloca() would
appear on the stack in the middle of the space forthe function arguments.
SEE ALSO
brk(2), longjmp(3), malloc(3)