代码之家  ›  专栏  ›  技术社区  ›  drigoSkalWalker

C/Glib内存管理{无悬空引用>whyy!??}

  •  1
  • drigoSkalWalker  · 技术社区  · 15 年前

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

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

    请注意,“”之间的参数是字符串,因此,在函数_名称中:

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


    (由于数据指针指向未保留的内存地址,导致引用悬空)。

    但它似乎没有发生,程序运行良好。为什么?在C语言中,传递给函数的参数存储在堆栈中,所以,堆栈中的数据点实际上是内存?

    非常感谢。

    2 回复  |  直到 12 年前
        1
  •  5
  •   caf    15 年前

    在C程序中引入字符串常量时,将创建一个具有静态存储持续时间的未命名、不可修改的对象。“静态存储持续时间”是指它在程序的整个生命周期内都有效。

    因此,当您的代码中包含以下内容时:

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

    为了节目的生命 . 通常,它们存储在文本段中,与程序代码本身的存储方式相同。

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

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

        2
  •  0
  •   Dave Gamble    15 年前

    有三件事是正确的:

    要么: 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_堆栈(256);在函数名之后,查看是否继续工作。