5

I have a C program that implements a stack.

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


struct node{
    int data;
    struct node *link;
};

struct stack{
    struct node *head;
    struct node *data_node;
};

int push(struct stack *a_stack, int i){
    a_stack->data_node = malloc(sizeof(struct node));
    if(a_stack->data_node == NULL){
        puts("Error: Cannot allocate sufficient memory.");
        exit(1);
    }
    a_stack->data_node->data = i;
    a_stack->data_node->link = a_stack->head;
    a_stack->head= a_stack->data_node;
    return 0;
}

int pop(struct stack *a_stack){
    if(a_stack->head==NULL){
        return '\n';
    }
    int temp = a_stack->head->data;
    a_stack->data_node = a_stack->head;
    a_stack->head = a_stack->head->link;
    free(a_stack->data_node);
    return temp;
}

int minimum(struct stack *a_stack){
    if(a_stack->head==NULL){
        return '\n';
    }
    int min = a_stack->head->data;
    struct node *a_node = a_stack->head;
    while(a_node!=NULL){
        if(min>a_node->data){
            min = a_node->data;
            a_node = a_node->link;
        }
    }
    return min;
}

int init_stack(struct stack *a_stack){
    a_stack->head = NULL;
    a_stack->data_node = NULL;
}

int handle_input(struct stack *test){

    char* input_string = (char*)malloc(20);
    scanf("%s", input_string);
    // gets(input_string);

    char* pop_cmd = "-";
    char* min_cmd = "min";
    int num;

    if (strcmp(pop_cmd, input_string) == 0){
        printf("%d\n", pop(test));
    }

    else{
        if (input_string[0] == 'm'){
            printf("%d\n", minimum(test));
        }
        else{
            num = atoi(input_string);
            push(test, num);
        }   
    }

    return 0;
}


int main(void){

    int no_of_input, counter;

    struct stack test;
    init_stack(&test);

    scanf("%d", &no_of_input);

    for(counter=no_of_input; counter>0; counter=counter-1){
        handle_input(&test);
    };

    return 0;
}

The problem is if I want to enter 'min' which is the command for calculating the minimum element of the array, the program waits forever on input. After searching around for quite a while I still have no idea why this is happening.

tarashish
  • 1,945
  • 21
  • 32
  • would it be because you're using a char pointer inside your handle_input method? char* input_string = (char*)malloc(20); scanf("%s", input_string); – user2277872 Aug 18 '13 at 16:41
  • `scanf` on most systems won't return until you type Enter. (This is called line buffering.) Are you doing that? – Gene Aug 18 '13 at 16:41
  • @Gene yes. I have tried enter and Ctrl + D. But still nothing. – tarashish Aug 18 '13 at 16:43
  • 2
    **Don't. Use. `scanf()`.** [`man 3 fgets`](http://pubs.opengroup.org/onlinepubs/009695399/functions/fgets.html). –  Aug 18 '13 at 17:41
  • Yes not `fgets()` avoid buffer-overflow: and [reading a line using `scanf()` not good?](http://stackoverflow.com/questions/17294809/reading-a-line-using-scanf-not-good/17294869#17294869) – Grijesh Chauhan Aug 18 '13 at 18:22

2 Answers2

4

The scanf don't wait but you have infinite loop problem. In function minimum(), you only conditionally update a_node to next node in linked list:

  int min = a_stack->head->data;  //note
  struct node *a_node = a_stack->head; //note

   while(a_node!=NULL){
        if(min > a_node->data){<-- "Always evaluates FALSE because: min is a_node->data"
            min = a_node->data;
            a_node = a_node->link; <--"Should NOT be here"
        }
        a_node = a_node->link; <--"but it should be here"
    }

Also, if condition (min > a_node->data) is always evaluates false because of the reason:

min is a_stack->head->data and a_node is a_stack->head so min == a_node->date and min > a_node->data always evaluates false because you updated a_node in if body.

Additionally I figured out that you have memory leak in the function handle_input(). You should free() dynamically allocated memory explicitly. Read my suggestion below:

int handle_input(struct stack *test){
    char* input_string = malloc(20); <-- "No need to type case"  
    // code here
    free(input_string);  <-- "Add this"
    return 0;
}
Grijesh Chauhan
  • 57,103
  • 20
  • 141
  • 208
0

Also, in:

int init_stack(struct stack *a_stack){
    a_stack->head = NULL;
    a_stack->data_node = NULL;
}

It should return void instead of int I think.

and min_cmd in handle_input() is unused.

Joohwan
  • 2,374
  • 1
  • 19
  • 30