i wrote a linked list meant to store cpu information. this is a simple input-and-store program and unfortunately get memory leaks. here is the code:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<math.h>
unsigned input_unsigned_number(void);
double input_double_number(void);
char * gets_s(char ** ptr_to_ptr);
struct cpu_specs {
    /* cpu_specs is a tag of structure */
    char * vendor_id;
    char * cpu_model;
    double cpu_MHz;
    unsigned cache_size: 16; /* set up 16-bit fields */
    unsigned clflush_size: 16; /* set up 16-bit fields */
    struct cpu_specs * next;
};
/* set up the structure declaration */
int main(void) {
    struct cpu_specs * head_to_cpu_stru = NULL;
    struct cpu_specs * previous, * current, * temp;
    char MAX_input[1024];
    fputs("Input the vendor's id(input sole [Enter] to terminate input): ", stdout);
    current = (struct cpu_specs * ) malloc(sizeof(struct cpu_specs));
    /* allocates sizeof(struct cpu_specs) bytes in the midst of uninitialized memory. */
    while (gets_s( & (current - > vendor_id)) != NULL &&
        current - > vendor_id[0] != '\0') {
        if (head_to_cpu_stru == NULL) head_to_cpu_stru = current;
        /* assign the first allocated momery of a pointer to structure cpu_specs to head_to_cpu_stru. */
        else previous - > next = current;
        /* assign the non-first allocated momery of a pointer to structure cpu_specs to previous->next. */
        current - > next = NULL;
        /* set current->next to be NULL. */
        fputs("Input the cpu model(input sole [Enter] to terminate input): ", stdout);
        if (gets_s( & (current - > cpu_model)) == NULL &&
            current - > cpu_model[0] == '\0') break;
        fputs("Input the cpu_MHz(cpu_MHz must be multiplier of 100): ", stdout);
        current - > cpu_MHz = input_double_number();
        fputs("Input the cache_size(cache_size<=65536 and cache_size must be power of 2): ", stdout);
        current - > cache_size = input_unsigned_number();
        fputs("Input the clflush_size(clflush_size<=65536 and clflush_size must be power of 2): ", stdout);
        current - > clflush_size = input_unsigned_number();
        temp = current;
        current = (struct cpu_specs * ) malloc(sizeof(struct cpu_specs));
        /* allocates sizeof(struct cpu_specs) bytes in the midst of uninitialized memory again. */
        previous = temp;
        /* assign the current allocated memory of a pointer to structure cpu_specs to previous. */
    }
    /* gather and store cpu specs from your input. */
    if (head_to_cpu_stru == NULL) puts("No any cpu specs.!");
    else {
        puts("here are all cpu speces:");
        puts("vendor_id\tcpu_model\tcpu_MHz\tcache_size\tclflush_size");
    }
    for (current = head_to_cpu_stru; current - > next != NULL; current = current - > next)
        printf("%s\t%s\t%.2fMHz\t%uKB\t%uKB\n", current - > vendor_id,
            current - > cpu_model, current - > cpu_MHz, current - > cache_size, current - > clflush_size);
    /* show cpu specs in a list */
    for (current = head_to_cpu_stru; current - > next != NULL; current = current - > next)
        free(current);
    puts("program done!");
    return 0;
}
double input_double_number(void) {
    double decimal_number;
    _Bool input_check;
    while ((input_check = fscanf(stdin, "%lf", & decimal_number)) != 1 &&
        fmod(decimal_number, 100.00) == 0) {
        if (input_check != 1) scanf("%*s");
        fprintf(stdout, "invalid input, enter this number again: ");
    }
    return decimal_number;
}
unsigned input_unsigned_number(void) {
    unsigned decimal_number;
    _Bool input_check;
    while ((input_check = fscanf(stdin, "%u", & decimal_number)) != 1 &&
        decimal_number <= 65536 && (decimal_number & decimal_number - 1) == 0) {
        if (input_check != 1) scanf("%*s");
        fprintf(stdout, "invalid input, enter this number again: ");
    }
    return decimal_number;
}
char * gets_s(char ** ptr_to_ptr) {
    unsigned i;
    void * alloc_check;
    char MAX_input[1024];
    if (fgets(MAX_input, 1024, stdin)) {
        for (i = 0; MAX_input[i] != '\n' && MAX_input[i] != '\0' && i < 1024; i++);
        if (MAX_input[i] == '\n') MAX_input[i] = '\0';
        if (( * ptr_to_ptr = (char * ) malloc((strlen(MAX_input) + 1) * sizeof(char))) == NULL)
        /*because the spaces where pointers inside structure point are not allocated and initialized. */
        {
            perror("fail to allocation.\n");
            exit(EXIT_FAILURE);
        }
        strcpy( * ptr_to_ptr, MAX_input);
        return *ptr_to_ptr;
    } else return NULL;
}
input_double_number(), input_decimal_number() are input processings. gets_s() take functionality of  initialization memory space where vendor_id, cpu_model points as well as string input.
i could input the first entry in list. when it comes to the second one, it couldn't go further and crash in memory leaks. here is GDB LeakSanitizer:
Direct leak of 40 byte(s) in 1 object(s) allocated from:
    #0 0x7fe5e708dbc8 in malloc (/lib/x86_64-linux-gnu/libasan.so.5+0x10dbc8)
    #1 0x7fe5e79fe8da in main /home/brushmonk/linkedlist.c:44
    #2 0x7fe5e6c570b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)
Direct leak of 40 byte(s) in 1 object(s) allocated from:
    #0 0x7fe5e708dbc8 in malloc (/lib/x86_64-linux-gnu/libasan.so.5+0x10dbc8)
    #1 0x7fe5e79fe5ab in main /home/brushmonk/linkedlist.c:23
    #2 0x7fe5e6c570b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)
Indirect leak of 9 byte(s) in 2 object(s) allocated from:
    #0 0x7fe5e708dbc8 in malloc (/lib/x86_64-linux-gnu/libasan.so.5+0x10dbc8)
    #1 0x7fe5e79ff286 in gets_s /home/brushmonk/linkedlist.c:93
    #2 0x7fe5e79fe917 in main /home/brushmonk/linkedlist.c:26
    #3 0x7fe5e6c570b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)
Indirect leak of 3 byte(s) in 1 object(s) allocated from:
    #0 0x7fe5e708dbc8 in malloc (/lib/x86_64-linux-gnu/libasan.so.5+0x10dbc8)
    #1 0x7fe5e79ff286 in gets_s /home/brushmonk/linkedlist.c:93
    #2 0x7fe5e79fe6b2 in main /home/brushmonk/linkedlist.c:35
    #3 0x7fe5e6c570b2 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x270b2)
SUMMARY: AddressSanitizer: 92 byte(s) leaked in 5 allocation(s).
did i write a wrong gets_s()function and use a pointer to pointer as argument to lead crash?
 
    