I wanted to write a standard stack in C but I am not sure if my stk_size() function could work on other platforms except for my 32bit pc. I read that its not good to cast a pointer to int. But what could be a better implementation? I dont want to add a "size"-variable because its redundant in my eyes.
Here are some parts of the source:
#define MAX_STACK_SIZE 100
typedef struct stk stack;
struct stk
{
/* Stack */
int * stk;
/* Pointer to first free element of stack */
int * sp;
};
void stk_init(stack* s)
{
/* Allocate memory for stack */
s->stk = malloc(sizeof(s->stk) * MAX_STACK_SIZE);
/* Set stack pointer to first free element of stack -> 0 */
s->sp = s->stk;
}
int stk_size(stack* s)
{
开发者_运维知识库 return ((int) s->sp - (int) s->stk) / sizeof(int *);
}
int main(int argc, char * argv[])
{
stack * s;
stk_init(s);
}
Thank you!
You can just use (s->sp - s->stk)
. Subtracting pointers yields a ptrdiff_t, which is a signed integral type.
For starters, you have a bug. You've allocated no space for your stack
object. You want either
int main(int argc, char * argv[])
{
stack s;
stk_init(&s);
}
or
int main(int argc, char * argv[])
{
stack * s = malloc(sizeof(stack));
stk_init(s);
}
And as for your question, I see @Crashworks has already answered it while I typed this.
In stk_init
You should be using
s->stk = malloc(sizeof(int) * MAX_STACK_SIZE);
because stk
is an int *
. In other words, your stack is composed of int
s.
In stk_size
you should do this:
return s->sp - s->stk;
When you subtract pointers in C, C takes into account the size of the object they point to (which in this case is an int
).
It's a silly idea, but if you really wanted to, you would do it like this : ((int) s->sp - (int) s->stk) / sizeof(int);
No need to cast, and no need to divide so long as you want your answer in ints
size_t stk_size(stack* s)
{
return (s->sp - s->stk);
}
Don't cast both pointers to an int. Subtract the pointers and cast the result to an int, unsigned int (if you know s->sp is always >= s->stk). This eliminates the need to divide by sizeof(int*) as well.
There is a standards-defined type, intptr_t
which is guaranteed to be large enough that it can store either an int
or any pointer type. Use that.
For example, if you were on a platform where int
is 32-bits but a pointer is 64-bits, intptr_t
would be a 64-bit type.
精彩评论