简体   繁体   中英

C printing a linked list not working?

I am reading from a file and trying to add it into a linked list and then traversing through the linked list to print the content out. I have a little trouble since my output is not printing the entire linked list, but only the last element multiple times. I have posted code down below and I have posted only snippets, and have removed error checking for brevity.

typedef struct Node{
    char* data;
    struct Node* next;
} NODE;

NODE* head = NULL;
NODE* tail = NULL;

int main(int argc, char* argv[])
{
    char buffer[1024];
    FILE* fp = fopen(argv[1], "r");
    while(fscanf(fp, "%1023s", buffer) == 1)
    {
        addNode(buffer);
    }
    print_linked_list(head);
    return 0;
}

void print_linked_list(NODE* head)
{
    NODE* ptr = head; 
    while(ptr != NULL)
    {
        printf("%s ", ptr -> data);
        ptr = ptr -> next;
    }
}

void addNode(char* str)
{
    NODE* newNode = createNode(str);
    if(head == tail && tail == NULL)
    {
        head = newNode;
        tail = newNode;
        head -> next = NULL;
        tail -> next = NULL;
    }
    else
    {
        tail -> next = newNode;
        tail = newNode;
        tail -> next = NULL;
    }
}

NODE* createNode(char* str)
{
    NODE* newNode = malloc(sizeof(NODE));
    newNode -> data = malloc((1 + strlen(str)) * sizeof(char));
    newNode -> data = str;
    newNode -> next = NULL;
    return newNode;
}

So if a file contains some text like "how are you", I am expecting my output to be printed as "how are you", but all I get is "you you you". How do I fix this?

At

newNode -> data = malloc((1 + strlen(str)) * sizeof(char));
newNode -> data = str;

did you wanted to do a string copy ( strncpy() ) from str to newNode->data ?

With newNode->data = str; the pointer is copied, the contents (eg "how are you") is not copied.

A simple way might be

newNode->data = strdup(str);

From http://man7.org/linux/man-pages/man3/strdupa.3.html

  The strdup() function returns a pointer to a new string which is a duplicate of the string s. Memory for the new string is obtained with malloc(3), and can be freed with free(3). 

newNode->data = str; is the problem. You're malloc ing space for a string, assigning that address to newNode->data , then immediately overwriting the address to that malloc ed space with the address to str , which actually is the address of buffer all the way from main . Not only does this create a memory leak, but it explains your behavior. Each time you create a node, you're assigning newNode->data to the address of buffer , so when the last word "you" is stored in buffer , this is the string all the nodes print. What you really want to do is strcpy (or something equivalent) the string from str into your newly malloc ed space. You should also check the return value of malloc first to make sure it returned a valid pointer:

#include <string.h>
....

if (newNode->data != NULL)
{
  strcpy(newNode->data, str);
}
else
{
   // handle error
}

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