C pointer based growable stack
I suggest that you do more error checking:


malloc or realloc may fail.
I can initialize the stack with negative capacity.
I can pop more elements than I pushed.


In all these cases, your implementation silently swallows the errors and accesses invalid addresses.

As πάντα ῥεῖ said in comments, if you want to store generic elements that exceed void* in size, you need to allocate memory for them and let the void* point to them, e.g.:

typedef struct {
    // ...
} BigStruct;

// pushing
BigStruct* data = malloc(sizeof(BigStruct));
// initialize *data
stack_push(&amp;stack, data);

// popping
BigStruct* data = stack_pop(&amp;stack);
// use *data
free(data);


Some small issues:


It is not common to cast the result of malloc or realloc in C.
If the stack is initialized to capacity 0, then the stack will never grow and elements will be stored at invalid positions.  A solution is to adjust the capacity to 1 automatically.