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 preventingnewStackSize
being 0 if trying to push elements. Only occurrence wherenewStackSize
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 <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
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(&s, 4);
for(int i = 0; i < 25; i++)
{
stack_push(&s, i + 1);
}
stack_pop(&s);
stack_push(&s, 88);
stack_push(&s, 25);
while (!stack_isEmpty(&s))
{
printf("The top of the stack is %d.\n", stack_peek(&s));
stack_pop(&s);
printf("The size of the stack is %u.\n", s.stackSize);
}
}
void stack_initialize(stack *p, unsigned int capacityIncrement)
{
p->elementData = NULL;
p->stackSize = 0;
if (capacityIncrement == 0)
{
capacityIncrement++;
}
p->capacityIncrement = capacityIncrement;
p->elementCount = 0;
}
int stack_push(stack *p, int value)
{
if(p->elementCount == p->stackSize)
{
if(stack_realloc(p, p->stackSize + p->capacityIncrement) == 1)
{
return 1;
}
}
p->elementData[p->elementCount] = value;
p->elementCount++;
return 0;
}
void stack_pop(stack *p)
{
if(!stack_isEmpty(p))
{
p->elementCount--;
if(p->elementCount == 0 || p->stackSize - p->elementCount >= p->capacityIncrement / 2 + p->capacityIncrement)
{
stack_realloc(p, p->stackSize - p->capacityIncrement);
}
}
}
int stack_peek(const stack *p)
{
if(!stack_isEmpty(p))
{
return p->elementData[p->elementCount - 1];
}
return 0;
}
static int stack_realloc(stack *p, unsigned int newStackSize)
{
if (newStackSize > 0)
{
void *temp = realloc(p->elementData, sizeof(*p->elementData) * newStackSize);
if(temp == NULL)
{
return 1;
}
p->elementData = temp;
}
else
{
stack_destroy(p);
}
p->stackSize = newStackSize;
return 0;
}
void stack_destroy(stack *p)
{
free(p->elementData);
p->elementData = NULL;
}
bool stack_isEmpty(const stack *p)
{
return p->elementCount == 0;
}
void stack_setCapacityIncrement(stack *p, unsigned int capacityIncrement)
{
p->capacityIncrement = capacityIncrement;
}
unsigned int stack_getCapacityIncrement(const stack *p)
{
return p->capacityIncrement;
}
unsigned int stack_getNumberOfElements(const stack *p)
{
return p->elementCount;
}
unsigned int stack_getSize(const stack *p)
{
return p->stackSize;
}
p->stackSize = 0;
tostack_destroy()
. it may be called independently of other functions. – chux Sep 14 '14 at 13:42stack_setCapacityIncrement()
? newsize inpop()
is a problem givenCapacityIncrement
could be >stackSize
. Maybestack_realloc(p, p->elementCount);
Suggest elminateingstack_setCapacityIncrement()
– chux Sep 14 '14 at 17:00typedef struct
forStack
to be lowercase (stack
)? That wasn't recommended to you in your last review, and is what I would consider not following modern C conventions. – syb0rg Sep 14 '14 at 17:50