alloca
alloca 是GNU libc中的内存分配函数。
void func()
{
void* p = alloca(size);
// do something using p
// ...
}
一般来说,alloca 的内存是在调用alloca的函数func 的栈上分配的,当func 返回或者异常退出的时候,分配的内存或自动释放。
以上说的是一般的情况。下面说说不一般的情况:
在HP-UX 系统上时,或者在其他的一些系统并且使用c++ 编译器时。在这些系统上,alloca是基于malloc的模拟。这种模拟并不会在func 返回时立马释放内存,而是在下一次调用alloca的时候才会释放。
需要注意的是,GCC 3.1 and 3.2可以把调用alloca的调用者 func 给内联。当这种情况发生时,alloca申请的内存直到func的调用者FUNC 返回的时候才会释放。就像下面那样:
void FUNC()
{
// some code...
func();
}
如果 在FUNC 循环调用func ,像下面这样,
void FUNC()
{
for(int i = 0; i < 9999999; i++)
{
func();
}
}
很容易造成栈溢出。
为了防止栈溢出,可以使用一下属性来禁止func 内联
#ifdef __GNUC__
__attribute__ ((__noinline__))
VLA
VLA 全称是variable-leng array ,是C99的标准,当时在C11却已到了GCC的语言拓展中。
一般来说,在C语言中,声明数组的时候,需要用一个常量指定数组的长度。
就像下面这样
int array1[16];
const int arr2Len = 32;
int array2[arr2Len];
但是,有了VLA 之后,我们可以向下面这样动态指定数组的长度
float read_and_process(int n)
{
float vals[n];
for (int i = 0; i < n; ++i)
vals[i] = read_val();
return process(n, vals);
}