feverDream
feverDream

Reputation: 283

Passing a Structure to a Generic Linked List

I am tyring to use a generic linked list for my project. For reference, I am following this implementation made by David Muto. My aim is to parse user-information(user-name and other details) from a plain text file and load these into my linked-list.

typedef struct {
char *user_name;
char *password;
char *friends;
}user_info;

Here is the code-flow.

list users;
list_new(&users,sizeof(user_info*),free_users);
init_server(&users);
list_for_each(&users,iterate_users);
list_destroy(&users);

Parsing is done in init_server(). In it the user_info struct is allocated and reference to tokens are copied into it. After this I make a call to list_append().

list_append()

void list_append(list *list, void *element){
listNode *node = malloc(sizeof(listNode));
node->data = malloc(list->elementSize);  
node->next=NULL;
memcpy(node->data,element,list->elementSize);

if(list->logicalLength == 0){
  list->head = list->tail = node;
}else {
  list->tail->next=node;
  list->tail=node;
}

list->logicalLength++;
}

Problem

Only the username reference is present in all the elements in the list. Here are the values of the element( structure reference passed to list_append()) and the head of the the list after the call returns.

(gdb) print *(user_info*)element
$31 = {username = 0x603270 "trudy", password =
0x603290"areyouthereyet",friends=0x6032b0 "bob;alice\n"}    

(gdb) print *(user_info *)list->head->data
$36 = {username = 0x603270 "trudy", password = 0x0, friends = 0x0}

Upvotes: 0

Views: 478

Answers (2)

Jay
Jay

Reputation: 14471

What is the list->elementSize set to?

Another potential issue:

You're storing pointers to the memory where the strings are. Suppose you parse a character string then store a pointer. Later if the string is deallocated the pointer will be aimed at whatever gets placed there later. It will be very difficult to debug. Make sure your strings remain during the time you use your list.

Upvotes: 1

Crowman
Crowman

Reputation: 25908

This:

sizeof(user_info*)

should be this:

sizeof(user_info)

You want the size of the struct itself, not the size of a pointer to it. Right now, your memcpy() call is not copying all the data as a result.

Similarly, listNode *node = malloc(sizeof(listNode)) should probably be listNode *node = malloc(sizeof(*node)) for the same reason. I'm assuming node->data = malloc(list->elementSize); will be correct once you're passing the right size to list_new().

Upvotes: 2

Related Questions