Hello,
I've tried to create a stack-like implementation in C, (basically storing integers to a buffer in a "stackish" way), however I've been experiencing some problems with my implementation --- specifically on Windows systems.
.....
typedef struct __stack {
int* content;
int no;
} stack_t;
.....
int PopFromStack(stack_t* stack)
{
int a = stack->content[stack->no];
stack->no--;
int* new_content_stk = (int*)malloc(stack->no * sizeof(int));
for (int i = 0; i < stack->no - 1; i++)
{
new_content_stk[i] = stack->content[i];
}
free(stack->content);
stack->content = new_content_stk;
return a;
}
However, when I call this procedure it generates a SIGTRAP (reported by GDB) exception exactly at "free(stack->content)" I'm pretty sure this is a case of stack corruption and my program is running where it isn't supposed to...
Any ideas about how I go on to solve this problem?
Assembler output from "gcc -S" (in case anyone asks for it):
....
L18:
movl 8(%ebp), %eax
movl 4(%eax), %eax
subl $1, %eax
cmpl -12(%ebp), %eax
jg L19
movl 8(%ebp), %eax
movl (%eax), %eax
movl %eax, (%esp)
call _free
movl 8(%ebp), %eax
movl -20(%ebp), %edx
movl %edx, (%eax)
movl -16(%ebp), %eax
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
...
...which looks pretty okay from my point of view.
EDIT: Thanks to OriginalGriff, I've used the method posted in his answer, and it works flawlessly! Here's the method by him (in code) if anyone cares about this in future :)
#define DEFAULT_STACK_SIZE 16*sizeof(int)
#define STACK_UFLOW_ERR -1
typedef struct __stack {
int* content;
int top_of_stack;
int stack_count;
}
......
stack_t* CreateStack(void)
{
stack_t* new_stack = (stack_t*)malloc(sizeof(stack_t));
new_stack->content = NULL;
new_stack->top_of_stack = 0;
new_stack->stack_count = 0;
return new_stack;
}
int PushtoStack(stack_t* stack, int object)
{
if (stack->stack_count == stack->top_of_stack){
if (stack->stack_count == 0){
int* new_buf = (int*)malloc(DEFAULT_STACK_SIZE);
memset((void*)new_buf, 0, DEFAULT_STACK_SIZE);
stack->stack_count = 16;
stack->content = new_buf;
}
else {
int* new_buf = (int*)malloc(stack->stack_count * 2 * sizeof(int));
memset((void*)new_buf, 0, stack->stack_count * 2 * sizeof(int));
memcpy(new_buf, stack->content, stack->stack_count * sizeof(int));
free(stack->content);
stack->content = new_buf;
stack->stack_count = stack->stack_count * 2;
}
}
stack->content[stack->top_of_stack] = object;
stack->top_of_stack++;
return 0;
}
int PopFromStack(stack_t* stack)
{
if (stack->top_of_stack == 0){
return STACK_UFLOW_ERR;
}
else {
stack->top_of_stack--;
return stack->top_of_stack;
}
}
Any more improvements/suggestions? :)