C / Glib内存管理{没有悬挂参考> WHYY!??}

时间:2009-08-05 03:56:38

标签: c glib

我有一个用未定义参数调用函数的程序,如下所示:

#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 */ }

请注意,“”之间的参数是字符串,因此,在function_name:

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

因此,如果数据指向va_list中的参数,当函数返回时,指向数据的teomeically,转为无效,并且也在garray中。  (导致悬空引用,因为数据指针,指向内存地址不保留更多)。

但似乎没有发生,该计划运行良好。为什么?并且,在C中,传递给函数的参数存储在堆栈中,那么,数据点生存在堆栈中的确是内存吗?

thnkx很多。

2 个答案:

答案 0 :(得分:5)

在C程序中引入字符串常量时,会创建一个具有静态存储持续时间的未命名,不可修改的对象。 “静态存储持续时间”意味着它适用于程序的生命周期。

所以当你的代码中有这个时:

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

字符串“arg2”和“arg3”是字符串常量 - 它们存在于程序存储器的某处,存在于程序的生命周期。通常这些都存储在文本段中,与程序代码本身的方式相同。

实际传递给function_name()的内容 - 可能是在堆栈上 - 是那些字符串常量的指针。这就是你的GArray最终存储的内容 - 指向那些字符串常量的指针。

(请注意,用作数组初始化程序的字符串不是字符串常量)。

答案 1 :(得分: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”,它存储在可执行文件的字符串部分中,而不是堆或堆栈上,因此它们将无限期地存在。