views:

41

answers:

2

I am curious why this code works:

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);
}

This works, but pointing to the memory address of a functions local variable is a big no-no, right?

But if i used a structure pointer and malloc, that would be the correct way, right?

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);
}
+3  A: 

You are right, passing a pointer to something that is allocated on the stack (and therefore goes away when the function returns, is wrong).

Passing a pointer to a heap allocated variable is fine.

"It works" is an illusion. You are returning a pointer to a stack-allocated variable in the first code example.

The pointer will point to garbage -- try dereferencing it...

rmk
"The pointer will point to garbage -- try dereferencing it.." - he did try dereferencing it. Unfortunately the garbage it printed looked just like what he might expect the value to be if it weren't garbage. That's one of the problems with garbage - sometimes it looks perfectly fine.
Michael Burr
Hmm... agreed. It is pure coincidence. I guess that's what confused the OP.
rmk
+3  A: 

The first version working is just dumb luck. Try randomly calling something else after test_func returns but before you call printf.

The second version is correct. Of course, you didn't free the heap memory, but whether that matters at the end of a program is a matter of debate.

Marcelo Cantos