Question

I implemented stack by using pointers. It is compiling and working but it doesn't underflow when the stack is empty. It gives me some garbage value. I think the problem is something in the create_stack function. I am not getting segfaults no matter how much data is popped from the stack which is odd.

Can anyone help?

Here is my complete implementation of stack by pointers.

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

enum action {PUSH = 1, POP, TOP, QUIT};

typedef struct node
{
    int data;
    struct node *lower;

}stack_node;

void clear_screen(void)
{
    system("cls");
}

static enum action get_user_action(void)
{
    int choice = 0;
    do
    {
        clear_screen();
        printf("%d Push data\n"
               "%d Pop Data\n"
               "%d See the top of the stack\n"
               "%d Exit\n\n"
               "Enter your choice -> ", PUSH, POP, TOP, QUIT);
        scanf("%d", &choice);
    } while (choice != PUSH && choice != POP && choice != TOP && choice != QUIT);
    return (enum action) choice;
}

void create_stack(stack_node **top, int *status)
{
    *top = malloc(sizeof(stack_node));

    *status = PUSH - 1;
    if (*top == NULL){
        *status = PUSH;
    }
}

void push(stack_node **top_stack, int *status, int data)
{
    *status = PUSH - 1;
    stack_node *node = malloc(sizeof(node));
    if (node == NULL)
    {
        *status = PUSH;
        return;
    }

    node -> data = data;
    if (*top_stack == NULL){
        node -> lower = NULL;
    }
    else{
        node -> lower = *top_stack;
    }
    *top_stack = node;
}

int pop(stack_node **top_stack, int *status)
{
    *status = PUSH - 1;
    if (*top_stack == NULL){
        *status = POP;
        return -1;
    }

    stack_node *node = *top_stack;
    int data = node -> data;
    *top_stack = node -> lower;
    free(node);

    return data;
}

int see_top(stack_node **top_stack, int *status)
{
    *status = PUSH - 1;
    if (*top_stack == NULL){
        *status = POP;
        return -1;
    }

    return (*top_stack) -> data;
}

int main(void)
{
    enum action choice;
    int status;

    stack_node *top = NULL;
    create_stack(&top, &status);

    if (status == PUSH)
    {
        printf("Not enough memory\n");
        return 1;
    }

    while ((choice = get_user_action()) != QUIT)
    {
        clear_screen();
        int data;
        switch (choice)
        {
        case PUSH:
            printf("Enter data to be pushed -> ");
            scanf("%d", &data);
            push(&top, &status, data);
            if (status == PUSH){
                printf("Not enough memory\n");
            }
            break;
        case POP:
            data = pop(&top, &status);
            if (status == POP){
                printf("Stack underflow\n");
            }
            else{
                printf("The data is %d\n", data);
            }
            break;
        case TOP:
            data = see_top(&top, &status);
            switch (status)
            {
            case POP:
                printf("Nothing in the stack\n");
                break;
            default:
                printf("The data at top is %d\n", data);
            }
            break;
        default:
            assert(!"You should not have reached this.");
        }
        getchar();
        getchar();
    }
}
Was it helpful?

Solution

When you create the stack you allocate space for a node -- and don't fill it with anything. So after the call to create_stack() you have a blank node on your stack already. I guess you don't want that, doing just

void create_stack(stack_node **top, int *status)
{
   *top = NULL;
   *status = PUSH -1;
}

will work just fine. You allocate the memory during the push() call anyway any you check for top_stack == NULL during the functions. Alternatively you could have a flag in your stack node to indicate it's not used (then during push you'd not create a new one) but that's too complex for what you want here.

OTHER TIPS

In create_stack() function you allocate memory and doesn't initialize it to any thing. Its data and lower part remain garbage.

When you pop elements if (*top_stack == NULL) condition never becomes true (becomes garbage value was not null) and so after remove all node it returns garbage value.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top