Jack
Jack

Reputation: 33

Creating stack in c for structs

I'm having a great deal of issue of implementing a stack for a certain struct. I have made this stack...

struct com_stack
{
  unsigned el_num;
  command_t *stk;
  unsigned top;
};
typedef struct com_stack *com_stack_t;

I've also created couple of functions to utilize the stack.

com_stack_t build_com_stack(unsigned num)
{
  com_stack_t s;
  s=malloc(sizeof(*s));
  s->el_num=num;
  s->stk=(command_t*)malloc((sizeof(command_t))*num);
  s->top=0;
  return s;
}

void com_push (com_stack_t s, command_t input)
{
  if(s->top == (s->el_num - 1))
  {
    s->el_num+=64;
    s->stk=(command_t)realloc(s->stk, sizeof(struct command) * s->el_num);
  }
  s->stk[s->top]=input;
  s->top++;
}

command_t com_pop (command_t)
{
  if(s->top==0)
    error(1,0, "nothing to pop");
  s->top--;
  return s->stk[s->top];
}

I run into issues when a push then pop the struct pointer out. So command_t is a pointer for a struct which has a member that is a char** within a union. While running the following test it works fine by itself, but I run into segmentation faults when I utilize the stack.

...
command_t com;
com=(command_t)malloc(sizeof(struct command));
com=build_scom_command(buffer, b_start, b_end);
com_stack_t cm_st;
//cm_st=(com_stack_t)malloc(sizeof(struct com_stack));
cm_st=build_com_stack(50);
com_push(cm_st,com);
command_t com_two;
com_two=com_pop(cm_st);
char* temp;
temp=(char*)malloc(1000);
temp=com_two->u.word;
unsigned i=0;
while(temp[i]!=NULL)
  printf("%c",temp[i++]);
...

The first element of char** (com_two->u.word where word is the name for char**) is the string I would like to test, but at the while loop I run into segmentation faults. Any advice or help on how to handle the stack would be greatly appreciated.

edit After all the helpful input I still have the seg fault. If everything seems fine here then I should probably check my original code (a mess at this point). Any other input would be greatly appreciated and if I ever do solve this problem I will post what I did and attribute credit. Thanks

edit 2 Had to change the pop function to decrement before returning. fixed the code, so the above is now in working order.

Upvotes: 2

Views: 212

Answers (1)

David Ranieri
David Ranieri

Reputation: 41017

You need to reserve space for s

com_stack_t build_com_stack(unsigned num)
{
  com_stack_t s;
  s->el_num=num;
  ...
  return s;
}

cm_st=(com_stack_t)malloc(sizeof(struct com_stack));
cm_st=build_com_stack(50);

should be

com_stack_t build_com_stack(unsigned num)
{
  com_stack_t s;
  s = malloc(sizeof(*s));
  s->el_num=num;
  ...
  return s;
}

com_stack_t cm_st = build_com_stack(50);

If you want to use (pass) the pointer allocated outside the build function:

void build_com_stack(com_stack_t s, unsigned num)
{
  s->el_num=num;
  ...
  /* return s; There is no need to return */
}

cm_st = malloc(sizeof(struct com_stack)); /* Don't cast malloc */
build_com_stack(cm_st, 50);

And as pointed out by @Qix

struct com_stack
{
  unsigned el_num;
  command_t *stk;
  unsigned top;
} <-- You are missing a semicolon

Upvotes: 1

Related Questions