1. Rather than print to `buf` and then copy to `pointer->data`, skip the middle-man while(fgets(pointer->data, sizeof pointer->data, f) != NULL) 2. Rather than start count at 1, start at 0 and skip the final decrement. int size = 0; while (...) { ... size++; } // size--; 3. Simplify `malloc()` usage, IMO this style easier to maintain and less error prone. // root = malloc(sizeof(struct node)); // pointer->next = malloc(sizeof(struct node)); root = malloc(sizeof *root); pointer->next = malloc(sizeof *(pointer->next)); 4. IMO, initializing the complete structure promptly after memory allocation is a good thing. (Also with `root`) pointer->next = malloc(sizeof *(pointer->next)); pointer = pointer->next; pointer->next = NULL; pointer->data[0] = '\0'; pointer->other_fields = 0; // or pointer->next = calloc(1, sizeof *(pointer->next)); 4. Checking if `malloc()` returned `NULL` is good also. 4. Like the setting the pointer to `NULL` after `free()`. A good compiler will optimize out if it can, but good to scrub pointers when done. free(pointer); pointer = NULL;