你不能按照你的建议去做。alloca
是一种非常特殊的野兽,它只能在函数体内显式调用,而不能在函数调用的参数表达式中调用。
请注意,没有标准版本的alloca
. C 标准和 POSIX 都没有描述这个函数。
您公开的替代方法,alloca
重新定义为内联函数调用__builtin_alloca
不起作用:除其他问题外,返回的指针__builtin_alloca()
仅在调用者返回之前有效,无论它是否内联。
linux 手册页非常明确:
[...]
描述
该alloca()
函数在调用者的堆栈帧中分配 size 个字节的空间。当被调用的函数alloca()
返回给它的调用者时,这个临时空间会自动释放。
返回值
该alloca()
函数返回一个指向分配空间开头的指针。如果分配导致堆栈溢出,则程序行为未定义。
[...]
符合
此功能不在 POSIX.1 中。
有证据表明该alloca()
功能出现在 32V、PWB、PWB.2、3BSD 和 4BSD 中。在 4.3BSD 中有一个手册页。Linux 使用 GNU 版本。
笔记
该alloca()
函数依赖于机器和编译器。对于某些应用程序,与使用malloc(3)
plus相比,使用它可以提高效率free(3)
。在某些情况下,它还可以简化使用longjmp(3)
或
的应用程序中的内存释放siglongjmp(3)
。否则,不鼓励使用它。
因为分配的空间是在堆栈帧内分配的,所以如果函数返回被调用或alloca()
跳过,该空间会自动释放。longjmp(3)
siglongjmp(3)
alloca()
如果指向它的指针只是超出范围,则分配的空间不会自动释放。
不要尝试free(3)
分配的空间alloca()
!
GNU 版本注意事项
alloca()
通常,gcc(1)使用内联代码将调用转换为。当给出-ansi
、-std=c89
、-std=c99
或
-std=c11
选项且不包含标题时,不会执行此操作<alloca.h>
。否则,(没有-ansi
or-std=c*
选项)glibc 版本的
<stdlib.h>
包含<alloca.h>
和包含以下行:
#ifdef __GNUC__
#define alloca(size) __builtin_alloca (size)
#endif
如果有人拥有此功能的私有版本,则会产生混乱的后果。
代码被内联的事实意味着不可能获取这个函数的地址,或者通过链接不同的库来改变它的行为。
内联代码通常由一条调整堆栈指针的指令组成,并且不检查堆栈溢出。因此,没有NULL
错误返回。
错误
如果堆栈帧无法扩展,则没有错误指示。(然而,在分配失败后,SIGSEGV
如果程序试图访问未分配的空间,它很可能会收到一个信号。)
在许多系统alloca()
上不能在函数调用的参数列表中使用,因为保留的堆栈空间alloca()
将出现在函数参数空间中间的堆栈上。