Search code examples
cstackdynamic-memory-allocationreallocfunction-definition

How Can I Know If This Program Works As i Intended( Dynamic stack )


enter code herei was watching a video in data structures in C , and when i understand the abstract view of the concept i go try implementing it without watching the implementation in the video , and what i implement wasn't in the video, the video was affording stack(static array and linked list). so i thought maybe i try my own that is using (dynamic array), and the program did work but i'm still in doubt if it 100% work without any side effect .it's just that i can't believe the program works. this program is intended to solve the overflow when pushing new value in the stack and without wasting memory space

(my doubts are : if it reallocate memory each time i push a new value correctly )

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


int *ptr;
int top = -1;
int size = sizeof(int) ;

void Push(int x);
void Pop();
int Top();
char isEmpty();

int main(){

    Push(1);
    Push(2);
    printf("%d\n", *(ptr+top));
    Pop();
    printf("%d\n", *(ptr+top));
    printf("top = %d, is empty : %c", Top(), isEmpty());


    return 0;
}

void Push(int x){
    if(top == -1){
        ptr = (int* )malloc(size);
        *ptr = x;
        top++;
    }
    else{
        realloc(ptr, size * (top + 1));
        *(ptr+top+1) = x;
        top++;
    }

}

void Pop(){
    if(top == -1){
        return;
    }
    free(ptr+top);
    realloc(ptr, size * top - 1);
    top--;
}

int Top(){
    if(top != -1){
    return *(ptr+top);
    }
    printf("Empty Stack\n");
    return 0;
}

char isEmpty(){
    if(top == -1){
        return 'T';
    }
    return 'F';
}



Solution

  • Your program incorrectly manages memory.

    For example in the function Push the address of the reallocated memory is lost

    realloc(ptr, size * (top + 1));
    

    So this statement

    *(ptr+top+1) = x;
    

    in general results in undefined behavior.

    Moreover in this call of realloc

    realloc(ptr, size * (top + 1));
    

    the expression (top + 1) yields an incorrect number of allocated elements.

    In the function Pop there is the same problem

    realloc(ptr, size * top - 1);
    

    and again the used expression size * top - 1 within the function is invalid.

    Also there is used an incorrect pointer expression to free memory

    free(ptr+top);
    

    You have to pass to the function free a pointer that was returned by allocation function malloc, calloc or realloc.

    The function Top does not check whether the stack is empty that again can invoke undefined behavior.

    Pay attention to that it is not a good design when functions depend on global variables. It would be better to declare a structure that will specify properties of the stack. For example

    struct Stack
    {
        int *base;
        size_t top;
    };
    

    Then in main you could write

    int main( void )
    {
        Stack stack = { .base = NULL, .top = 0 };
        //...
    

    The function isEmpty could look the following way

    int isEmpty( const struct Stack *stack )
    {
        return stack->top == 0;
    }
    

    and be called for example like

    if ( isEmpty( &stack ) ) puts( "The stack is empty." );
    

    The function Push could look the following way

    int Push( struct Stack *stack, int item )
    {
        int *tmp = realloc( stack->base, ( top + 1 ) * sizeof( *base ) );
        int success = tmp != NULL;
    
        if ( success )
        {
            stack->base = tmp;
            stack->base[top++] = item;
        }
    
        return success;
    }
    

    The function Top can look like

    int Top( const struct Stack *stack, int *item )
    {
        if ( stack->top != 0 )
        {
            *item = stack->base[top - 1];
        }
    
        return stack->top != 0;
    }
    

    and be called like for example

    int item;
    
    if ( Top( &stack, &item ) )
    {
        printf( "top = %d\n", item );
    }
    else
    {
        puts( "The stack is empty." );
    }