Why is my content of linked list disappear when it exit a function?

Viewed 113

I was trying to scan a file and add the data into the link list ,then print the operation into an output file. I succeed in printing the operation to the output file, but the content of my link list is empty when I try to access it.

I then check the address of each node created and linked and found no problem, when it is inside the function the link list worked fine but not in main().

Input.txt
3
1 Coding Mark Programming
1 Cooking Minnie Culinary
1 Gardening Penny Botany

This code is not completed but it contain my problem:

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

struct book {
    char *title;
    char *author;
    char *subject;
};
struct library {
    struct book collection;
    int num_books;
    struct library *next;
};

void AddBook(FILE *IF, FILE *OF, struct library** thislib);//function prototype

int main(void){
    FILE *IF,*OF;
    int sel,numOp,i;
    struct library *Lib=NULL;//declare head pointer
    if(((IF=fopen("library.txt","a+"))==NULL)||((OF=fopen("output.txt","w"))==NULL)){//open input and output file
        printf("File cannot be open!");
    }
    else{   
        fscanf(IF," %d",&numOp);    //scan the number of operation from file
        for(i=0;i<numOp;i++){       //Loop according to number of operation
            if(feof(IF))            //if file pointer reach EOF break
                break;  
            fscanf(IF," %d",&sel);  //scan the type of operation
            switch(sel){
            case 1: 
                AddBook(IF,OF,&Lib);    //add the book if sel is 1
                break;
            case 2:
                
                break;
            }
            printf("%s ", Lib->collection.title);   // print the title of the book but it show nothing
        }
    }
    return 0;
}

void AddBook(FILE *IF, FILE *OF, struct library** thislib){
    char title[30],author[30],subject[20];          //declare variable to hold data
    struct library *temp=NULL;                      //create a new node
    struct library *ptr=*thislib;               //create a pointer that point to head of link list
    temp=(struct library*)malloc(sizeof(struct library));   //allocate memory for the new node
    fscanf(IF," %s %s %s" ,title,author,subject);
    temp->collection.title=title;       // put the data into link list
    temp->collection.author=author;
    temp->collection.subject=subject;
    temp->next=NULL;
    if((*thislib)==NULL){
        (*thislib)=temp;                // if there is no content in link list put temp into head
    }
    else{
        while (ptr->next!=NULL)
        {
            ptr=ptr->next;              //put node at the end of link list
        }
        ptr->next=temp;
    }
    fprintf(OF,"The book %s author %s subject %s has been added to the library.\n",title,author,subject);
    printf("%s ",(*thislib)->collection.title);  //this work fine but it keep updating, weren't it suppose to have the same value
}
1 Answers
  1. You forget to #include <stdlib.h>. Your code is wildly undefined because you sheared off the high bits of the return of malloc().

  2. You returned pointers to stack arrays.

    temp->collection.title=title;       // put the data into link list
    temp->collection.author=author;
    temp->collection.subject=subject;

Gotta dupe those. strdup() is your friend:

    temp->collection.title=strdup(title);       // put the data into link list
    temp->collection.author=strdup(author);
    temp->collection.subject=strdup(subject);
  1. This line is failing on your test case: fscanf(IF," %d",&numOp); The input doesn't match the pattern; you enter the loop with an undefined numOp. (I trivially fixed this by correcting the input file. You should always check the return of scanf.)

  2. This scanf results in a read problem causing nonsense.

    fscanf(IF," %s %s %s" ,title,author,subject);

but there are four space-separated fields in your input.

  1. Your debug output displays the first item in the linked list, but you append to the end of the list every time, so it will not change.

Explanation of "sheared off the high bits":

The implicit declaration from missing #include <stddef.h> would be int malloc(size_t), which is wrong. On 32 bit platforms this works, but on 64 bit platforms it doesn't. int gets upcast to void * which does not result in the correct value.

Let's say that malloc() returned 0x104C000010. The return address looks like this (endianness does not matter here for reasons I'm not going to get into now)

 0                                                                                                                            63
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|0|0|0|0|1|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|1|1|0|0|1|0|0|0|0|0|1|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

But the return is interpreted as a 32 bit integer (most 64 platforms have sizeof(int) = 4), so it will be interpreted as

 0                                                            31
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|0|0|0|0|1|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|1|1|0|0|1|0|0|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

and when cast to struct library * this results in

 0                                                                                                                            63
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|0|0|0|0|1|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|1|1|0|0|1|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|0|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

which is 0x4C000010. Oops that points somewhere else. Anything can happen, but most likely a crash.

Related