C / Glib Memory Management {нет висящей ссылки> Whyy! ??} - PullRequest
1 голос
/ 05 августа 2009

У меня есть программа, которая вызывает функцию с неопределенными аргументами, например:

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

обратите внимание, что аргументы между "" являются строками, поэтому в имени_функции:

static void function&#95;name (GArray &#42;garray, ...) {
  ... /&#42; code &#42;/
  char &#42;data;<br />
  data = va_arg (garray, gchar &#42;);
  g&#95;array&#95;append&#95;val (garray, data);<br />
  ... /&#42; code &#42;/
}

Таким образом, если данные указывают на аргумент в va_list, когда функция возвращает, теоретически данные указывают, становятся недействительными, и также в массиве.
(вызывая висячую ссылку, потому что указатель данных указывает на адрес памяти, не зарезервированный больше).

Но этого не происходит, программа работает хорошо. Зачем? и, в C, аргументы, переданные функциям, хранятся в стеке, так что жизнь точек данных в стеке действительно памяти?

Thnkx много.

Ответы [ 2 ]

5 голосов
/ 05 августа 2009

Когда вы вводите строковую константу в программе на Си, создается неназванный, неизменяемый объект со статической продолжительностью хранения. «Статическое время хранения» означает, что оно длится всю жизнь программы.

Итак, когда у вас есть это в вашем коде:

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

Строки "arg2" и "arg3" являются строковыми константами - они существуют где-то в памяти программы, в течение жизни программы . Часто они хранятся в текстовом сегменте так же, как и сам код программы.

То, что фактически передается в function_name () - предположительно в стеке, - это указатели на эти строковые константы. И это то, что ваш GArray в конечном итоге хранит - указатели на эти строковые константы.

(Обратите внимание, что в качестве инициализатора массива используется строка , а не строковая константа).

0 голосов
/ 05 августа 2009

Верно одно из трех:

Либо: 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); после имени_функции и посмотрите, продолжают ли все работать.

Или: 3) Вы используете const char "string" s, которые хранятся в секции string исполняемого файла, а не в куче или в стеке, поэтому они будут сохраняться бесконечно.

...