简体   繁体   中英

I cant find the error of my linked list( why is my head pointer moving?)

I have tried so many times to set my head pointer pointing to the first node. At first(in the empty list) it correctly points the first node. But after the first loop, the head pointer points to the newnode linked. Actually now Im quite unsure about my whole code as well.

int main(void){
struct library *head = NULL; //set the head pointer to NULL
int option;
printf("Enter the number:");


while((option = getchar())!= 9){
switch(option){
case '1':
    {
    char title[1000];
    char author[1000];
    char subject[1000];
    printf("Enter title of the book you want to add:");
    scanf("%s",title);
    printf("Enter author of the book you want to add:");
    scanf("%s",author);
    printf("Enter subject of the book you want to add:");
    scanf("%s",subject);
    add_book(title,author,subject,&head);
    printf("successful! and head pointer is pointing to %s\n",head->collection.title);
    break;
    }
  }
}


void add_book(char title[],char author[],char subject[], struct library ** head){
struct library *current;
struct library *newnode = malloc(sizeof(struct library));
newnode->collection.title = title;
newnode->collection.author = author;
newnode->collection.subject = subject;      // assigning value inside newnode
newnode->num_books = 0;
newnode->next = NULL;                       // assign NULL value to the end of newnod

//when the head is NULL which means when the list is empty
if(*head == NULL)
{
    current = newnode;
    *head = current;

    return;
}

else
{
    current = *head;                //assign the first node to current pointer
    //find the last node of the list
    while(current->next != NULL)
    {
        current = current->next;
    }
    current->next = newnode;                    // link the last node to new node
    return;
}
}

This is struct for this

struct book {
char* title;
char* author;
char* subject;
};

struct library {
struct book collection;
int num_books;
struct library* next;
};

The lifetime of char title[1000]; , char author[1000]; , and char subject[1000]; ends when execution reaches the end of the block inside case '1': { /*... */ } . Once this happens, the pointers that were assigned in add_book become dangling pointers - pointing to invalid memory.

To remedy this, you must ensure the lifetime of your strings matches the lifetime of the structures that contain them. This can be done either by allocating enough space in the structure itself

struct book {
    char title[1000];
    /* etc. */
};

or by dynamically allocating enough space for a copy of each string. In any case you must copy the string to this memory ( man 3 strcpy ).

If it is available on your system, man 3 strdup does both steps of the second form at once. Otherwise, it is roughly the same as strcpy(malloc(strlen(source_string) + 1), source_string);.

Also note that the scanf specifier %s is as dangerous as gets when used without a field-width specifier (eg, scanf("%999s", buffer) ), as it can potentially overflow your buffer.


An example program. Enter strings one-by-one, and terminate with EOF CTRL+D (Windows: CTRL+Z , RETURN ).

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct link {
    char *string;
    /* alternatively: char string[512]; */
    struct link *next;
};

void add_link(struct link **root, const char *string) {
    struct link *node = calloc(1, sizeof *node);
    node->string = strdup(string);
    /* alternatively: strcpy(node->string, string) */

    if (*root) {
        struct link *tail = *root;

        while (tail->next)
            tail = tail->next;

        tail->next = node;
    } else
        *root = node;
}

int main(void) {
    struct link *head = NULL;

    while (1) {
        char buffer[512];

        if (!fgets(buffer, sizeof buffer, stdin))
            break;

        /* remove newline */
        buffer[strcspn(buffer, "\n")] = '\0';

        add_link(&head, buffer);
    }

    for (struct link *node = head, *next; node; node = next) {
        next = node->next;
        printf("STRING: %s\n", node->string);
        free(node->string);
        free(node);
    }
}

Note: in a real program you should always check the return values of your memory allocating functions ( malloc , calloc , strdup , etc.) as they can fail.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM