2009-08-05 19 views
1

我有打電話與不確定參數的函數,這樣的程序:C /油嘴內存管理{沒有懸掛參考> WHYY ??!}

#include <stdargs.h>
... /* code */ int main() {
GArray *garray = g_array_new (FALSE, FALSE, sizeof (char *)); /* the code above initialize the GArray, and say that the garray expect a pointer to char. */
function_name (garray, "arg2", "arg3" /* and so on ... */);
... /* code */ }

需要注意的是,在「」之間的ARG遊戲串,因此,在功能_名稱:

static void function_name (GArray *garray, ...) { 
    ... /* code */ 
    char *data;
data = va_arg (garray, gchar *); g_array_append_val (garray, data);
... /* code */ }

     所以,如果數據指向的va_list一個說法,當函數返回時,teorically數據指出,轉向失效,並在garray了。
(導致一個懸掛引用,因爲數據指針,指向一個內存地址不保留更多)。

     但它似乎沒有發生,程序運行良好。爲什麼?並且,在C中,傳遞給函數的參數被存儲在堆棧中,那麼,數據是否在堆棧中確實存在內存?

thnkx很多。

回答

5

當您在C程序中引入字符串常量時,將創建一個具有靜態存儲持續時間的未命名的,不可修改的對象。 「靜態存儲時間」意味着它在程序的整個生命週期中生存。

所以,當你有這樣的代碼:

function_name (garray, "arg2", "arg3" /* and so on ... */); 

字符串「ARG2」和「ARG3」是字符串常量 - 它們的某處存在程序存儲器中,該程序的生活。通常這些都存儲在文本段中,與程序代碼本身的方式相同。

實際傳遞給函數名()的東西 - 大概在堆棧上 - 指針指向那些字符串常量。這就是你的GArray最終存儲的指針 - 指向這些字符串常量的指針。

(注意,用作數組初始值的字符串是而不是的字符串常量)。

0

一個三件事情是真實的:

或者: 1)g_array_append_val正在該字符串的副本。

或者: 2)一旦棧被再次覆蓋,事情就會中斷。

void burn_stack(int size) 
{ 
    char data[8]={0,0,0,0,0,0,0,0}; 
    size-=8; 
    if (size>0) burn_stack(size); 
} 

嘗試調用burn_stack(256);在function_name之後,看看事情是否繼續工作。或者:3)你使用的是const char「string」,它存儲在可執行文件的字符串部分,而不是堆或堆棧中,因此它們將無限期地持久化。

+0

錯誤 - 這些字符串常量具有靜態存儲持續時間,所以它們不太可能存儲在堆棧中。指向他們的指針可能是,但這不是問題。 – caf 2009-08-05 05:03:00

+1

當然,他們是常數。我的錯。 – 2009-08-05 05:20:13