Dynamically-sized stack - follow-up 3 Follow up of - Dynamically-sized stack - follow-up 2

I've took the tips given to me, and what I did now is:


Use same case type for type stack and it's functions
Returning 1 if push failed due to an OOM exception otherwise return 0 if succeeded.
push could now only return a pointer to null due to OOM exception and not because of allocating 0 bytes, in stack_initialize capacitiyIncrement is set to 1 if it's 0 preventing newStackSize being 0 if trying to push elements. Only occurrence where newStackSize will be 0 is if trying to shrink the stack size and there're no elements left in the stack.
Made a stack_realloc() function to deal with all stack reallocations.
stack_destroy() function is now freeing the memory of the elements saved in the stack and not the actual stack object.




#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;stdbool.h&gt;

typedef struct
{
    int *elementData;
    unsigned int stackSize;
    unsigned int capacityIncrement;
    unsigned int elementCount;
} stack;

void stack_initialize(stack*, unsigned int);
int stack_push(stack*, int);
void stack_pop(stack*);
int stack_peek(const stack*);
static int stack_realloc(stack*, unsigned int);
void stack_destroy(stack*);
bool stack_isEmpty(const stack*);
void stack_setCapacityIncrement(stack*, unsigned int);
unsigned int stack_getCapacityIncrement(const stack*);
unsigned int stack_getNumberOfElements(const stack*);
unsigned int stack_getSize(const stack*);

int main()
{
    stack s;
    stack_initialize(&amp;s, 4);
    for(int i = 0; i &lt; 25; i++)
    {
        stack_push(&amp;s, i + 1);
    }
    stack_pop(&amp;s);
    stack_push(&amp;s, 88);
    stack_push(&amp;s, 25);
    while (!stack_isEmpty(&amp;s))
    {
        printf("The top of the stack is %d.\n", stack_peek(&amp;s));
        stack_pop(&amp;s);
        printf("The size of the stack is %u.\n", s.stackSize);
    }
}

void stack_initialize(stack *p, unsigned int capacityIncrement)
{
    p-&gt;elementData = NULL;
    p-&gt;stackSize = 0;
    if (capacityIncrement == 0)
    {
        capacityIncrement++;
    }
    p-&gt;capacityIncrement = capacityIncrement;
    p-&gt;elementCount = 0;
}

int stack_push(stack *p, int value)
{
    if(p-&gt;elementCount == p-&gt;stackSize)
    {
        if(stack_realloc(p, p-&gt;stackSize + p-&gt;capacityIncrement) == 1)
        {
            return 1;
        }
    }
    p-&gt;elementData[p-&gt;elementCount] = value;
    p-&gt;elementCount++;
    return 0;
}

void stack_pop(stack *p)
{
    if(!stack_isEmpty(p))
    {
        p-&gt;elementCount--;
        if(p-&gt;elementCount == 0 || p-&gt;stackSize - p-&gt;elementCount &gt;= p-&gt;capacityIncrement / 2 + p-&gt;capacityIncrement)
        {
            stack_realloc(p, p-&gt;stackSize - p-&gt;capacityIncrement);
        }
    }
}

int stack_peek(const stack *p)
{
    if(!stack_isEmpty(p))
    {
        return p-&gt;elementData[p-&gt;elementCount - 1];
    }
    return 0;
}

static int stack_realloc(stack *p, unsigned int newStackSize)
{
    if (newStackSize &gt; 0)
    {
        void *temp = realloc(p-&gt;elementData, sizeof(*p-&gt;elementData) * newStackSize);
        if(temp == NULL)
        {
            return 1;
        }
        p-&gt;elementData = temp;
    }
    else
    {
        stack_destroy(p);
    }
    p-&gt;stackSize = newStackSize;
    return 0;
}

void stack_destroy(stack *p)
{
    free(p-&gt;elementData);
    p-&gt;elementData = NULL;
}

bool stack_isEmpty(const stack *p)
{
    return p-&gt;elementCount == 0;
}

void stack_setCapacityIncrement(stack *p, unsigned int capacityIncrement)
{
    p-&gt;capacityIncrement = capacityIncrement;
}

unsigned int stack_getCapacityIncrement(const stack *p)
{
    return p-&gt;capacityIncrement;
}

unsigned int stack_getNumberOfElements(const stack *p)
{
    return p-&gt;elementCount;
}

unsigned int stack_getSize(const stack *p)
{
    return p-&gt;stackSize;
}
Its not a problem but this seems strange:

stack_realloc(p, p-&gt;stackSize - p-&gt;capacityIncrement);


Decreasing the size of the stack when you take elements out. This may cause a lot of work (in your code) if you are near a boundary and do a lot of push/pop combinations. It is unlikely that the memory is actually released by realloc() when shrinking anyway.