Двойная косвенность и структуры, переданные в функцию - PullRequest
1 голос
/ 31 марта 2010

Мне интересно, почему этот код работает:

typedef struct test_struct {
  int id;
} test_struct;

void test_func(test_struct ** my_struct)
{
test_struct my_test_struct;
my_test_struct.id=267;

*my_struct = &my_test_struct;
}

int main ()
{
test_struct * main_struct;
test_func(&main_struct);    
printf("%d\n",main_struct->id);
}

Это работает, но указание на адрес памяти локальной переменной функции - это большое нет-нет, верно?

Но если бы я использовал структурный указатель и malloc, это был бы правильный путь, верно?

void test_func(test_struct ** my_struct)
{
test_struct *my_test_struct;
my_test_struct = malloc(sizeof(test_struct));
my_test_struct->id=267;

*my_struct = my_test_struct;
}

int main ()
{
test_struct * main_struct;
test_func(&main_struct);    
printf("%d\n",main_struct->id);
}

Ответы [ 2 ]

3 голосов
/ 31 марта 2010

Первая работающая версия - просто тупая удача. Попробуйте случайно вызвать что-то еще после возврата test_func, но перед вызовом printf.

Вторая версия верна. Конечно, вы не освободили кучу памяти, но вопрос о том, имеет ли это значение в конце программы, является предметом споров.

3 голосов
/ 31 марта 2010

Вы правы, передавая указатель на что-то, что расположено в стеке (и, следовательно, исчезает, когда функция возвращается, неправильно).

Передача указателя на выделенную переменную кучи - это нормально.

«Это работает» - иллюзия. Вы возвращаете указатель на выделенную в стеке переменную в первом примере кода.

Указатель будет указывать на мусор - попробуйте разыменовать его ...

...