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);
}