alloca 和 變長數組(VLA)

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

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章