Dynamic Array Based Stack in C I wrote a dynamic stack in C that uses an array as a structure.  I tried to maintain O(1) for push and pop and believe I have done so.  I want to know what can be written in a cleaner way and if there are any non-trivial bugs.
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;

int push(int val, int *c);
int pop(int *c);

int *stack;

int main(){
    int *c = malloc(sizeof(int));
    stack = malloc(sizeof(int));
    *c = 0;
    int i;
    for(;;){
       printf(&quot;1. Push\n2. Pop\n3. Stack\n4. Quit\n&gt;&gt;&gt; &quot;);
       scanf(&quot;%d&quot;, &amp;i);
       if(i == 1){
           printf(&quot;Value: &quot;);
           scanf(&quot;%d&quot;, &amp;i);
           push(i, c);
       }
       else if(i == 2)
           printf(&quot;Value popped: %d\n&quot;, pop(c));
       else if(i == 3)
           for(int i = 0; i &lt; *c; i++)
               printf(&quot;%d\n&quot;, stack[i]);
       else
           break;
    }
    free(stack);
    return 0;
}

int push(int val, int *c){
    int *r;
    r = realloc(stack, ((*c)+1)*sizeof(int));
    if (r == NULL){
        free(stack);
        exit(0);
    }
    stack = r;
    stack[*c] = val;
    ++(*c);
    return *c;
}

int pop(int *c){
    if (!(*c)) return -1;
    int x = stack[(*c)-1];
    stack[(*c)-1] = NULL;
    int *r;
    printf(&quot;%d\n&quot;, *c);
    r = realloc(stack, ((*c)-1)*sizeof(int));
    if(r == NULL){
        free(stack);
        exit(0);
    }
    --(*c);
    stack = r;
    return x;
}

```
Create a struct that encapsulates all the details of a stack
The problem is that your stack just looks like a pointer to an int, indistinguishable from other pointers to ints. And the first element it points to is treated differently from the other elements. In this case, it is better to create a struct that keeps track of the allocated memory and the size of it, like so:
struct Stack {
    size_t size;
    int *data;
};

You initialize it as follows:
struct Stack stack = {0, NULL};

Now you should change push() and pop() to take a pointer to a struct stack:
void push(struct Stack *stack, int val) {
    stack-&gt;size++;
    int *new_data = realloc(stack-&gt;data, stack-&gt;size * sizeof *stack-&gt;data);

    if (!new_data) {
        // error handling here, or just
        abort();
    }
    
    stack-&gt;data = stack-&gt;new_data;
    stack-&gt;data[stack-&gt;size - 1] = val;
}

And similar for pop(). Note that it is common to have functions that operate on an object take the pointer to that object as the first parameter. Also, I made the function return void, there is no need to return the size of the stack size that information is already available to the caller.
Avoid using global variables
You should avoid using global variables if possible. My example code above no longer requires there to be a global stack. This change allows the code to manage multiple stacks without conflicts.
Add functions to create and destroy stacks
Instead of requiring the caller to know how to properly initialize a struct Stack and to free it after use, create functions that do this for you. That allows you to change the internals of struct Stack later, without having to change all the places where a stack is used.
Use a common prefix to avoid name conflicts
push() and pop() are very generic names. There are many more things that can have push and pop operations, such as FIFO queues. I recommend you use a common prefix for all data structures and functions for your stack. This can simply be Stack or stack if you think that is unlikely to conflict with anything else.