1

I'm working on a FIFO page replacement algorithm and have it almost working. My code uses scanf() to read in a page number then it adds that item to a linked list, up to 16 pages. However, if the page already exists in the lined list, it does not add the page to this list again. There are three page frames (slots). Everything works properly, but, it does not add that item to the list until scanf() reads another integer to add to the list. I am utterly confused.

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

typedef struct node {
    int num;
    struct node * next;
} node_t;

void print_list(node_t * head) {
    node_t * current = head;
    while (current != NULL) {
        printf("%d\n", current->num);
        current = current->next;
    }
}

int fault(node_t * head, int check) {
    node_t * current = head;
    while(current->next != NULL){
        if(current->num == check)
            return 0;
        current = current->next;
    }
    return 1;
}

void addNode(node_t * head, int num) {
    node_t * current = head;
    while (current->next != NULL) {
        current = current->next;
    }

    /* now we can add a new variable */
    current->next = malloc(sizeof(node_t));
    current->next->num = num;
    current->next->next = NULL;
}

int pop(node_t ** head) {
    int retnum = -1;
    node_t * nextNode = NULL;
    if (*head == NULL) {
        return -1;
    }
    nextNode = (*head)->next;
    retnum = (*head)->num;
    free(*head);
    *head = nextNode;
    return retnum;
}

///////////////////////////////////////////////////////

int main(){
    int num;
    int faults = 0;
    int n = 0;
    int j = 0;
    node_t * head = malloc(sizeof(node_t));
    if (head == NULL) {
        return 1;
    }
    head->num = -1;
    printf("Input page number up to 16 pages. Enter 'q' to quit.\n");
    for(j=0;j<16;j++){
        if(scanf("%d\n",&num) == 1) {

            if (fault(head, num) == 1 && n < 3) {
                n++;
                faults++;
                addNode(head, num);
            }
            else if (fault(head, num) == 1 && n >= 3) {
                pop(&head);
                addNode(head,num);
                faults++;
            }   
        }   
        else{
           int c = getchar();
           if( c == 'q' ){
               break;
           }
        }
        if (n == 1 && faults == 1)
            pop(&head);
        printf("\nPage Table:\n");
        print_list(head);
        printf("\nInput page number: \n");
    }
    printf("Number of page faults: %d\n", faults);
}

I ran it through gdb and it doesn't even call the addNode function until the second integer has been scanned.

(And yes I know scanf is garbage, I just didn't want to bother learning how to do something else)

Thanks for the help!

5
  • head->next is never initialized. Commented Apr 27, 2016 at 22:33
  • That didn't change anything when I did head->next = malloc(sizeof(node_t)); in main. Commented Apr 27, 2016 at 22:35
  • I wouldn't expect it to, and that's not a reasonable initialization. Please review the code path your code will take... performing the initialization in your comment would delay the undefined behavior by one iteration but it just makes head->next->next uninitialized. Commented Apr 27, 2016 at 22:36
  • gdb shows that there is literally no action being taken after the first integer is read from scanf. I have no idea what to do. Commented Apr 27, 2016 at 22:39
  • 1
    In scanf("%d\n" get rid of \n. And initialize head->next = NULL;. Commented Apr 27, 2016 at 22:41

1 Answer 1

1

Your code:

    if(scanf("%d\n",&num) == 1) {

should be :

    if(scanf("%d",&num) == 1) {

And head needs to be initialized.

    node_t * head = malloc(sizeof(node_t));
    if (head == NULL) {
    return 1;
}
head->next = NULL;
Sign up to request clarification or add additional context in comments.

5 Comments

That worked, thanks! I didn't realize that \n would delay the input.
@EthanF it would seem that you've taken these details directly from my comments. While I don't particularly care, attribution is expected when this happens. That said... the initialization of head->next should not occur until after it is known that head != NULL.
@mah Hi I am sorry you had such thought. This is not a hard question I really don't need to take details from others. I tested his code in my computer and both problems are very obvious. Yes you are right about the glitch in my code, it should be put after head null check. I'll make the change later, thank you for that. When I saw the problem during debugging I made this careless fix, probably in my mind, the chance of malloc returns NULL is almost impossible. Anyway, Hopefully no hard feelings.
I agree it's not a difficult problem and I certainly don't mean to say you stole it from me! Its just that my comments were on this page several (7 I think) minutes before you posted the answer, and as you can see, not only is your answer virtually identical to my comments but you went as far as to call out the same unrelated requirement of initializing head->next... so perhaps you can see how the concern came about. No hard feelings at all.
@mah Yes I get your point. You found the problem (the next = NULL one) without running the code, you're cool :D.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.