I'll point out a few obvious bugs:
>#include <stdio.h>
>#include <stdlib.h>
>#include <string.h>
>
>enum { VAL_FALSE = 0, VAL_TRUE = 1, SIZE_STACK = 10 };
I guess this is legal, but a little confusing to have constants from
different contexts defined in the same enum. Simpler to do:
#define false 0
#define true 1
#define SIZE_STACK 10
>struct myStack
>{
> int top;
>};
OK, but why not collect the actual stack and stack pointer together
in one place:
struct myStack {
int top;
struct myStruct *sof[SIZE_STACK+1];
};
>void initialize(struct myStack s);
>int stackEmpty(struct myStack s);
>void push(struct myStruct* arr[], struct myStack s, const char* ele);
>
>
>int main(void)
>{
> struct myStruct* sof[SIZE_STACK+1] = {0};
> struct myStack s;
>
> initialize(s);
> stackEmpty(s);
stackEmpty() has no side effects and you're ignoring its return
value, so why call it at all?
> push(sof, s, "CLC");
Here's a problem. s is a struct, and you're passing it
by value into push(). It's technically legal, but poor form, as
I'll point out a little further down. Should really have been
push(sof, &s, "CLC");
>
> return 0;
>}
>
>
>void initialize(struct myStack s)
>{
> s.top = 0;
>}
Here's your first bug. You passed s by value, then modified
it. But you only modified a copy. The original is still
untouched, which means it's still uninitialized.
Should have passed by reference instead:
initialize(&s);
...
void initialize(struct myStack *s)
{
s->top = 0;
}
>void push(struct myStruct* arr[], struct myStack s, const char* ele)
Second bug. Again, you're modifying a local copy of s, leaving the
original unchanged. Should have been:
void push (struct myStruct* arr[], struct myStack *s, const char *ele)
with all references to "s.top" changed to "s->top".
Finally, it would be better if push() returned a boolean value
indicating the the push had failed. Error messages are good,
but program detecting problems is better.
>{
> if(NULL == arr || NULL == ele)
> {
> fprintf(stderr, "IN: %s @%d: Invalid Args\n", __FILE__, __LINE__);
> }
> else if(SIZE_STACK <= s.top)
> {
> printf("Stack Full, Can not add anymore elements\n");
> }
> else
> {
> struct myStruct* p = malloc( 1 * sizeof *p);
> if(NULL == p)
> {
> fprintf(stderr, "IN: %s @%d: Out of Memory\n", __FILE__,
>__LINE__);
> }
> else
> {
> strcpy(p->title, ele);
Third bug. Here's your segfault. You're copying the data pointed to
by ele into the space pointed to by p->title, but you never allocated
any such space. p->title is uninitialized and the strcpy() is pretty
much guaranteed to fault.
Better would be to do:
p->title = strdup(ele);
plus a check to make sure that p->title isn't NULL.
> arr[s.top] = p;
> s.top += 1;
> }
> }
>}
Try this on for size:
#define true 1
#define false 0
typedef bool int;
#define SIZE_STACE 10
typedef struct {
int top;
struct myStruct *stack[SIZE_STACK];
} MyStack;
void
initialize(MyStack *s)
{
s->top = 0;
}
bool
push(MyStack *s, const char *ele)
{
struct myStruct *p;
if (s == NULL || ele == NULL) {
fprintf(stderr, "invalid pointer, yada yada\n");
return false;
}
if (s->top >= SIZE_STACK) {
fprintf(stderr, "full stack, yada yada\n");
return false;
}
if ((p = malloc(sizeof(*p))) == NULL ||
(p->title = strdup(ele)) = NULL)
{
fprintf(stderr, "out of memory, yada yada\n");
return false;
}
s->stack[s->top++] = p;
return true;
}
There are other tweaks and improvements you could make, but they're
not imporant.
--
-Ed Falk,
http://thespamdiaries.blogspot.com/