Stack implementation shows blank array in codeblock but works fine in online compiler

90 Views Asked by At

I have a simple stack implementation. I want to show the stack before pushing So If my stack size is 3, according to my implementation, it should print 0 0 0 But it is showing blank in codeblocks (version 20.03) but works fine in some online compiler

#include <stdio.h>
#include <stdbool.h>

void init_stack(int);
void push(int);
int pop();
int peek();
void print();

int top = -1;
int stack_size;
int stack[];

int main()
{
    printf("Size of your stack : ");
    scanf("%d", &stack_size);
    printf("This Stack Allows Only Integer Value!");
    stack[stack_size];

    init_stack(stack_size);

    bool t = true;
    while(t)
    {
        printf("\n\n1. Push\n2. Pop\n3. Peek\n4. isEmpty\n5. isFull\n6. Print Stack\n7. Exit");
        printf("\n\nChoose : ");

        int c;
        scanf("%d", &c);

        int Element;
        switch(c)
        {
        case 1 :
            printf("\n\nElement : ");
            scanf("%d", &Element);

            if(top < stack_size-1)
            {
                push(Element);
                printf("\nSuccessful...");
            }
            else printf("\n\tStack overflow!");
            break;

        case 2 :
            if(top > -1)
            {
                Element = pop();
                printf("\nPopped element is : %d", Element);
            }
            else printf("\n\tStack underflow!");
            break;

        case 3 :
            if(top > -1)
            {
                Element = peek();
                printf("\nTop element is : %d", Element);
            }
            else printf("\n\t");
            break;

        case 4 :
            if(top > -1) printf("\nStack is not empty.");
            else printf("\nStack is empty!");
            break;

        case 5 :
            if(top < stack_size-1) printf("\nStack is not full.");
            else printf("\nStack is full!");
            break;

        case 6 :
            printf("\n\nCurrent stack :");
            print();
            break;

        default :
            t = false;
        }
    }

    return 0;
}

void push(int Element)
{
    top++;
    stack[top] = Element;
}

int pop()
{
    int Element = stack[top];
    stack[top] = 0;  //deleting the element from the stack
    top--;
    return Element;
}

int peek()
{
    return stack[top];
}

void print()
{
    int i;
    for(i=0; i<stack_size; i++)
    {
        printf("\t%d", stack[i]);
    }
}

void init_stack(int n)
{
    int i;
    for(i=0; i<n; i++)
    {
        stack[i] = 0;
    }
}

Screenshots

Codeblocks

codeblocks output

Please point out my mistakes.

3

There are 3 best solutions below

1
On BEST ANSWER
  1. Avoid global variables. Pass your "stack" to functions which work on it via a function argument.

  2. To accomplish this you need all of your stack info as a value. You can use a struct to accomplish this.

  3. Use dynamic memory allocation to accomplish this.

E.g.

typedef struct stack {
    size_t capacity;
    size_t top;
    int *stack;
} stack_t;

stack_t *init_stack(size_t size) {
    stack_t *new_stack = malloc(sizeof(stack_t));
    if (!new_stack) return NULL;

    new_stack->stack = calloc(size, sizeof(int));
    if (!new_stack->stack) {
        free(new_stack);
        return NULL;
    }

    return new_stack;
}

bool push(stack_t *stack, int value) {
    if (!stack || stack->top >= stack->capacity - 1) {
        return false;
    }
        
    stack->stack[stack->top++] = value;
    return true;
}

// the other operations on a stack

Then in main you can now write:

int main(void) {
    size_t size;
    if (scanf("%zu", &size) != 1) return 1;

    stack_t *stack = init_stack(size);
    if (!stack) return 1;
    
    // operations on your stack.

    // free your stack

    return 0;
}
0
On

Thanks @WeatherVane for the solution.

#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>  // Added for malloc

void init_stack(int);
void push(int);
int pop();
int peek();
void print();

int top = -1;
int stack_size;
int* stack;  // Removed []

int main()
{
    printf("Size of your stack: ");
    scanf("%d", &stack_size);
    stack = (int*)malloc(sizeof(int) * stack_size);  // Corrected malloc usage
    printf("This Stack Allows Only Integer Value!");

    init_stack(stack_size);

    bool t = true;
    while (t)
    {
        printf("\n\n1. Push\n2. Pop\n3. Peek\n4. isEmpty\n5. isFull\n6. Print Stack\n7. Exit");
        printf("\n\nChoose: ");

        int c;
        scanf("%d", &c);

        int Element;
        switch (c)
        {
            case 1:
                printf("\n\nElement: ");
                scanf("%d", &Element);

                if (top < stack_size - 1)
                {
                    push(Element);
                    printf("\nSuccessful...");
                }
                else
                {
                    printf("\n\tStack overflow!");
                }
                break;

            case 2:
                if (top > -1)
                {
                    Element = pop();
                    printf("\nPopped element is: %d", Element);
                }
                else
                {
                    printf("\n\tStack underflow!");
                }
                break;

            case 3:
                if (top > -1)
                {
                    Element = peek();
                    printf("\nTop element is: %d", Element);
                }
                else
                {
                    printf("\n\tStack is empty!");
                }
                break;

            case 4:
                if (top > -1)
                {
                    printf("\nStack is not empty.");
                }
                else
                {
                    printf("\nStack is empty!");
                }
                break;

            case 5:
                if (top < stack_size - 1)
                {
                    printf("\nStack is not full.");
                }
                else
                {
                    printf("\nStack is full!");
                }
                break;

            case 6:
                printf("\n\nCurrent stack:");
                print();
                break;

            default:
                t = false;
        }
    }

    free(stack);  // Free the allocated memory
    return 0;
}

void push(int Element)
{
    top++;
    stack[top] = Element;
}

int pop()
{
    int Element = stack[top];
    stack[top] = 0;  // Deleting the element from the stack
    top--;
    return Element;
}

int peek()
{
    return stack[top];
}

void print()
{
    int i;
    for (i = 0; i <= top; i++)
    {
        printf("\t%d", stack[i]);
    }
}

void init_stack(int n)
{
    int i;
    for (i = 0; i < n; i++)
    {
        stack[i] = 0;
    }
}
0
On

This declaration of an array in the file scope

int stack[];

is a tentative definition of an array that is equivalent to the definition

int stack[1];

and its single element is zero initialized.

So this declaration does not make sense.

This statement within main:

stack[stack_size];

has no effect. It is an attempt to access a non-existent element of the previously declared file scope array with the index stack_size provided that stack_size is not equal to 0.

Instead of the file scope array you could declare a variable length array within the function main like:

int main()
{
    printf("Size of your stack : ");
    scanf("%d", &stack_size);
    printf("This Stack Allows Only Integer Value!");
    int stack[stack_size];
    //...

In this case you will need to change your functions adding one more parameter for the passed array to the functions as for example

#include <string.h>

//...

void init_stack( int stack[], int n )
{
    memset( stack, 0, n * sizeof( int ) );
}

Pay attention to that the function print should output only actual values in the stack. So it should be defined something like the following way

void print( void )
{
    for( int i = 0; i < top + 1; i++ )
    {
        printf("\t%d", stack[i]);
    }
}

But in any case it would be much better instead of using separate variables as the array, the variable top and the variable size to declare a structure that will contain these entities as its data members. For example:

struct Stack
{
    int size;
    int top;
    int *data;
};