Kyrol
Kyrol

Reputation: 3607

Create a generic stack implemented with a linked-list in C

I want to create a generic stack. I want to implement it with a linked-list.

I created this structures stack_l :

typedef struct stack
 {
   void * data;

   void (*copy)(void *o);

   struct stack *next;

 } stack_l;

I have some questions:


stack_l * Push( stack_l * head, void * d );

  1. Is it correct how I pass the pointer to the function copy?
  2. I have to implement it in the function Push??


Upvotes: 0

Views: 936

Answers (1)

bitmask
bitmask

Reputation: 34636

First of all, you do not require different identifiers for stack and stack_l. Now, to your questions:

Your Push function is incompatible with the type of the copy field in stack_l. If you want to include a pointer to (member-)functions in your struct to make it look like C++, you still have to pass your object to these functions.

Yes ,you have to implement your functionality somewhere, and that cannot be within the definition of struct stack. This means that you do need some sort of constructor function (you may call it newStack if you like). Your constructor must at least initialise your function pointers (if you want to keep them). If you opt not to keep these function pointers you can put the initialisation code well in your push routine, as you suggested:

stack_l* stackPush(stack_l* head, void* content) {
  // head might be NULL, meaning the stack is "empty" or it might be an actual pointer
  // we don't care
  stack_l* const front = malloc(sizeof(stack_l));
  *front = (stack_l){.data = content, .next = head};
  return front;
}

Note that you have to explicitly state what the empty stack is. So you may want to implement a constructor for clarity:

stack_l* stackCreateEmpty() {
  retun NULL;
}

And maybe even a destructor:

void stackDestroyEmpty(stack_l* s) {
  assert(s == NULL && "Tried to destroy non-empty stack.");
}

To your last question: As you see above, you have to use malloc to get space to hold your stack_l object, other than that, you do not need to allocate extra space for your void* member, as it is part of stack_l.

Upvotes: 1

Related Questions