2009-08-05 92 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