-2

I'm trying to implement a doubly linked list in C and I need to use an initialize function, while maintaining a size field. My code is as follows:

typedef struct element{
    struct element* next;
    struct element* prev;
    int value;
}element_t;

typedef struct linkedlist{
    element_t* head;
    element_t* tail;
    int size;
}linkedlist;

void init(linkedlist* list){
    list = malloc(sizeof(linkedlist));
    list->size = 0;
}

int main(int argc, char** argv){
    linkedlist* list;
    init(list);
    return 0;

When I'm trying to access list->size in the init function, I get the correct value, But when I try to access list->size from main the program returns a strange, large negative value (probably an address in hex).

Would like to know what I'm doing wrong. stdlib is included.

Triumphan
  • 19
  • 4

2 Answers2

5

You are only modifying a local copy of list which main will never see. You probably want to do something like this:

linkedlist* init(void) { // <<<
    linkedlist* list = malloc(sizeof(linkedlist)); // <<<
    list->size = 0;
    return list; // <<<
}

int main(int argc, char** argv){
    linkedlist* list = init(); // <<<
    return 0;
}

If you have to keep the original function signature, then you must not modify list within init. You could do something like this instead:

void init(linkedlist* /* const */ list){
    list->size = 0;
}

int main(int argc, char** argv){
    linkedlist list; //<<<
    init(&list); //<<<
    return 0;
Paul R
  • 208,748
  • 37
  • 389
  • 560
  • This works, but how should I implement the function signature: void init(linkedlist* list) which I'm limited to? – Triumphan Jan 03 '17 at 13:25
  • You can't - you either use the above method, or you use @dbush's method, or you do the `malloc` (or equivalent) outside `init` (e.g. in `main`), so that the `list` pointer is not modified. – Paul R Jan 03 '17 at 13:27
  • Very well, I'll keep on that - thanks – Triumphan Jan 03 '17 at 13:35
  • Another issue that annoys me - how come I can modify values of the structure (as done on the init function) while it is not yet allocated anywhere in the memory? – Triumphan Jan 03 '17 at 13:51
  • @Triumphan: C is a low level language which provides you with an infinite number of different ways to shoot yourself in the foot. Just because something *appears* to work you should never assume that it is correct to do so. – Paul R Jan 03 '17 at 14:30
  • @Triumphan Eh? `init` allocates `list` and then modifies it. – Jim Balter Jan 03 '17 at 15:57
2

In C, all parameters are pass by value. So the list variable in init is a copy of the value of list in main, and it is that copy that is being modified. So the change isn't seen outside of the function.

You need to pass the address of list into init, and change that function to accept a pointer-to-pointer.

void init(linkedlist **list){
    *list = malloc(sizeof(linkedlist));
    (*list)->size = 0;
}

int main(int argc, char** argv){
    linkedlist *list;
    init(&list);
    return 0;
}
dbush
  • 205,898
  • 23
  • 218
  • 273