Home > database >  Printing Linked List leads to strings with garbage values (C)
Printing Linked List leads to strings with garbage values (C)

Time:09-05

I was reading a linked list from a .txt file to fill the following node:

typedef struct node {
    
    int data;
    char* line;
    struct node* next;

} NODE;

The code works fine and reads the file into the linked list. I print out the string while each node is being initialized. However whenever I call the printList() function, the line string is always a garbage value. Sample run:

./a.out linkedlisttext.txt

data in readFile(): 4
string in readFile():  Hello world
address in readFile(): 0x1326067a0


data in readFile(): 28
string in readFile():  What is up world???
address in readFile(): 0x1326067c0


data in readFile(): 2124
string in readFile():  your mother
address in readFile(): 0x1326067e0


data in readFile(): 85
string in readFile():  more data
address in readFile(): 0x132606800


data in readFile(): 9421
string in readFile():  just a little more data
address in readFile(): 0x132606820


data in readFile(): 992
string in readFile():  are we almost there?
address in readFile(): 0x132606840


data in readFile(): 301
string in readFile():  we did it!
address in readFile(): 0x132606860

DATA:    4 | STRING �g`2
address in printList(): 0x1326067a0
DATA:   28 | STRING �g`2
address in printList(): 0x1326067c0
DATA: 2124 | STRING �g`2
address in printList(): 0x1326067e0
DATA:   85 | STRING h`2
address in printList(): 0x132606800
DATA: 9421 | STRING 0h`2
address in printList(): 0x132606820
DATA:  992 | STRING Ph`2
address in printList(): 0x132606840
DATA:  301 | STRING 
address in printList(): 0x132606860

Here is linkedlisttext.txt

4, Hello world
28, What is up world???
2124, your mother
85, more data
9421, just a little more data
992, are we almost there?
301, we did it!

and here is the code:

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

typedef struct node {
    
    int data;
    char* line;
    struct node* next;

} NODE;


struct node* readFile(FILE* fp, NODE* root) {
    char line[100];
    char* token;
    NODE* curr;
    NODE* prev;

    
    while(fgets(line, 100, fp) != NULL) {   
        
        curr = malloc(sizeof(struct node*));

        token = strtok(line, ",");
        
        curr->data = atoi(token);

        printf("\ndata in readFile(): %d\n", curr->data);
        
        token = strtok(NULL, "");
        curr->line = (char*) malloc(sizeof(token)    1);

        strcpy(curr->line, token);
        printf("string in readFile(): %s", curr->line);
        printf("address in readFile(): %p\n\n", curr->line);


        curr->next = NULL;  
    
        
        if(root == NULL) {
            root = curr;
        } else {
            NODE* travel = root;

            while(travel->next != NULL) {
                travel = travel->next;
            }

            travel->next = curr;

        }

        
    }

    return root;    

}

void printList(NODE* root) {
    
    struct node* temp = root;

    while(temp->next != NULL) {
        printf("DATA: M | STRING %s\n", temp->data, temp->line);
        printf("address in printList(): %p\n", temp->line);

        
        temp = temp->next;
    }

    printf("DATA: M | STRING %s\n", temp->data, temp->line);
    printf("address in printList(): %p\n", temp->line);

}

int main(int argc, char** argv) {
    
    FILE* fp = fopen(argv[1], "r");
    NODE* root = NULL;  

    if(fp == NULL) {
        return 0;
    }   

    root = readFile(fp, root);
    printList(root);
    
}

Any help is appreciated, thanks!

CodePudding user response:

curr->line = (char*) malloc(sizeof(token) 1);

As sizeof(token) always returns the size of pointer (8 bytes with most systems), not the length of the string, you are not allocating the sufficient buffer for line. Please try instead:

curr->line = malloc(strlen(token)   1);

As a side note, you are using the same name line for both the line buffer in the main function and the structure member name. They have individual namespaces and syntactically valid, but might be confusing for the future maintenance.

CodePudding user response:

This is highly suspect:

curr = malloc(sizeof(struct node*));

You are allocating memory for a struct node pointer but not for a struct node. Given the memory sizes of pointers and ints, subsequently assigning to curr->data may actually work, but then assigning to curr->line and curr->next is likely to get you in trouble.

Or not. Undefined behavior is inherently unpredictable.

  • Related