I’m currently writing a stack implementation in C. I need it to use as little memory as possible and be as fast as possible while still taking every data type I can throw at it, with multiples types in each stack. I decided to use void pointers for this, and got it working relatively quickly despite my rusty C. However, actually using it is quite ugly.
For testing the stack, I’m pushing integers with a loop. Actually passing the int as a void pointer is the issue.
My first inclination was to use &:
for (int i = 0; i < 20; i++){
stack_push(s, &i); //s is the stack_t pointer
}
However with closer inspection this obviously wouldn’t work, since i is destructively updated every step. Every element in the stack ends up as 20.
I’ve since turned to a very ugly solution:
for (int i = 0; i < 20; i++){
int* p = malloc(sizeof(void*));
*p = i;
stack_push(s, p);
}
This works, but presents two issues:
-
It’s ugly
-
I have to worry about memory management for every element of the stack. (and for some reason manually walking the stack and freeing every element still leaks memory…)
Is there a better way to do this without wasting unnecessary memory with a union and still being fast? Thanks.
If the types are going to be mixed, something needs to know what the type is.
If it is the client (or user) of the stack who will cast types back to their correct form, then that’s fine, but the size still needs to be available to the stack.
If the caller knows that too, the interface might look like:
void push(const int size, void* value);
void pop(const int size, void** valueptr);
I don’t think that will be robust in general, but if you are writing a compiler then it can generate all of the correct code, in the same was as the C compiler.
Internaly, I’d have two versions, one for debugging, which retains the value of size, and one for ‘performance’ which doesn’t. I;d wite the debugging one first.
I’d ditch the idea of pointers because
If the stack stores values, then once popped it has no responsibilty.
An implementation:
pop is the reverse,