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;