1

I am new to C and having trouble understanding why my_struct_ptr (main) is nil in the following example. How would I assign the address of a struct in the my_structs array to the my_struct_ptr pointer within the get_my_struct_by_name function?

struct my_struct { char *name; char *descr; char *value; } my_structs[3] = { {"a", "a description", "value 1"}, {"b", "b description", "value 2"}, {"c", "c description", "value 3"} }; int get_my_struct_by_name(char *name, struct my_struct *my_struct_ptr) { int i; for (i=0; i < (sizeof(my_structs)/sizeof(struct my_struct)); i++) { if (strcmp(name, my_structs[i].name) == 0) { my_struct_ptr = &my_structs[i]; printf("works: %s,%s,%s\n", my_struct_ptr->name, my_struct_ptr->descr, my_struct_ptr->value); return 0; } } return -1; } int main() { int res = 0; struct my_struct *my_struct_ptr; if (res = get_my_struct_by_name("b", my_struct_ptr)) return res; printf( "nil: %p\n", my_struct_ptr); printf("seg fault: %s,%s,%s\n", my_struct_ptr->name, my_struct_ptr->descr, my_struct_ptr->value); return res; } 

Edit: Adding example output to hopefully help others. Thank you to everyone who responded. This is exactly the help I was looking for!

Output:

[prompt ~]$ ./test works: b,b description,value 2 nil: (nil) Segmentation fault 
2
  • 1
    What is this "nil" you speak of? :-) Commented Mar 15, 2012 at 23:44
  • @Ed S. the printf %p specifier produces "(nil)" rather than address for my_struct_ptr in main. I updated the question to help clarify for others. thanks Commented Mar 16, 2012 at 0:25

3 Answers 3

4

You have to pass the pointer as a pointer (i.e. pass its address):

int get_my_struct_by_name(char *name, struct my_struct **my_struct_ptr) { // ^^^ // ... *my_struct_ptr = /* ... */ } int main() { struct my_struct * my_struct_ptr; get_my_struct_by_name(name, &my_struct_ptr); // ... } 

If you just pass the pointer by value, as you did, you only modify a local copy of the pointer, not the original pointer.

Moral: If you want a function to change a variable in the calling scope, you have to say & somewhere.

Sign up to request clarification or add additional context in comments.

Comments

1

The solution is to use pointer to pointer in your function get_my_struct_by_name. Notice addition * (asterisk) in the declaration, then in assignment (inside get_my_struct_by_name) and & ampersand in invokation (inside main). This way you are passing a pointer to your my_struct_ptr defined in main and assigning the right value directly to your variable in main.

This solution assumes that you are using pure C (in C++ having a reference to a pointer would be probably more convenient).

int get_my_struct_by_name(char *name, struct my_struct **my_struct_ptr) { int i; for(i=0; i < (sizeof(my_structs)/sizeof(struct my_struct)); i++) { if(strcmp(name, my_structs[i].name) == 0) { *my_struct_ptr = &my_structs[i]; printf("works: %s,%s,%s\n", my_struct_ptr->name, my_struct_ptr->descr, my_struct_ptr->value); return 0; } } return -1; } int main() { int res = 0; struct my_struct *my_struct_ptr; if (res = get_my_struct_by_name("b", &my_struct_ptr)) return res; printf( "nil: %p\n", my_struct_ptr); printf("seg fault: %s,%s,%s\n", my_struct_ptr->name, my_struct_ptr->descr, my_struct_ptr->value); return res; } 

Comments

0

If I recall correctly, you need to pass the address of the pointer and then dereference it inside of the routine. Since this is call by value, you need the address of the pointer passed to set the value of the pointer. I have update the routines below.

int get_my_struct_by_name(char *name, struct my_struct **my_struct_ptr) { int i; for (i=0; i < (sizeof(my_structs)/sizeof(struct my_struct)); i++) { if (strcmp(name, my_structs[i].name) == 0) { *my_struct_ptr = &my_structs[i]; printf("works: %s,%s,%s\n", my_struct_ptr->name, my_struct_ptr->descr, my_struct_ptr->value); return 0; } } return -1; } 

and then you need to take the address of the pointer and pass it in from the main routine.

if (res = get_my_struct_by_name("b", &my_struct_ptr)) return res; 

That way you can pass back the address of the structure.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.