运行时才可以确定栈空间大小的就要在运行时分配,如: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>intmain(int argc,char*argv[]){int n =rand();int buf[n*100]; buf[0] =1; buf[n*100-1] =0;return0;}
运行命令gcc -g -O0 -o main main.c,然后运行`objdump -dS main`得到如下反汇编后的指令,如果读者有汇编基础的话,很容易就看懂了。前面我们也有提及,分配栈帧时通常通过对寄存器rsp的调整来实现,因为栈是从高地址向低地址方向增长的,所以对栈的分配动作其实是sub指令对rsp寄存器做减法操作,重点关注虚线“---”标注的部分就可以了。
alloca-allocatememorythatisautomaticallyfreedSYNOPSIS#include <alloca.h>void*alloca(size_tsize);DESCRIPTIONThealloca() functionallocatessizebytesofspaceinthestackframeofthecaller.Thistemporaryspaceisautomaticallyfreedwhenthefunctionthat called alloca() returns to its caller.RETURNVALUEThealloca() functionreturnsapointertothebeginningoftheallocatedspace.Iftheallocationcausesstackoverflow,programbehaviorisundefined.CONFORMINGTOThisfunctionisnotinPOSIX.1-2001.Thereisevidencethatthealloca() functionappearedin32V,PWB,PWB.2,3BSD,and4BSD.Thereisamanpageforitin4.3BSD.LinuxusestheGNUversion.NOTESThealloca() functionismachine-andcompiler-dependent.Forcertainapplications,itsusecanimproveefficiencycomparedtotheuseofmalloc(3) plusfree(3).Incertaincases,itcanalsosimplifymemorydeallocationin applications that use longjmp(3) or siglongjmp(3). Otherwise, its use isdiscouraged.Becausethespaceallocatedbyalloca() isallocatedwithinthestackframe,thatspaceisautomaticallyfreedifthefunctionreturnisjumpedoverbyacalltolongjmp(3) orsiglongjmp(3).Donotattempttofree(3) spaceallocatedbyalloca()!...BUGSThereisnoerrorindicationifthestackframecannotbeextended. (However,afterafailedallocation,theprogramislikelytoreceiveaSIGSEGVsignalifitattemptstoaccesstheunallocatedspace.)Onmanysystemsalloca() cannotbeusedinsidethelistofargumentsofafunctioncall,becausethestackspacereservedbyalloca() wouldappearonthestackinthemiddleofthespaceforthefunctionarguments.SEEALSObrk(2), longjmp(3), malloc(3)