用C通用堆栈 [英] Generic Stacks in C
问题描述
我实现用C通用协议栈,我面临stackPop方法的问题。我的结构如下:
I am implementing generic stack in C and I am facing a problem in stackPop method. My struct is as follows:
Stack.h文件
typedef struct{
void *elems;
int elemSize;
int allocLength;
int logLength;
void (*freefnc)(void *);
} Stack;
void stackNew(Stack *s, int elemSize, void (*freefnc)(void *));
void stackDispose(Stack *s);
void stackPush(Stack *s, void *elemAddr);
void stackPop(Stack *s, void *target);
Stack.c
#inlcude<Stack.h>
void stackNew(Stack *s, int elemSize, void (*freefnc)(void *)){
s.allocLength = 4;
s.logLength = 0;
s.elemSize = elemSize;
s.elems = malloc(4*elemSize);
s.freefnc = freefnc;
}
void stackDispose(Stack *s){
if(s.freefnc!=NULL){
for(int i=0; i<s.logLength; i++){
freefnc((char *)s.elems+i*s->elemSize);
}
}
free(s.elems);
}
void Stringfree(void *elem){
free(*(char**)elem);
}
void stackPush(Stack *s, void *elemAddr){
if(s.alloclength == s.logLength){
stackGrow(s);
}
void *target = (char *)s.elems + s.logLength*s.elemSize;
memcpy(target,elemAddr,s.elemSize);
s.logLength++;
}
static void stackGrow(Stack *s){
s.allocLength*=2;
s.elems = realloc(s.elems, s.alloclength*s.elemSize);
assert(s.elems!=NULL);
}
void stackPop(Stack *s, void *elemAddr){
void *source = (char *)s.elems + (s.logLength-1)*s.elemSize;
memcpy(elemAddr,source,s.elemSize);
s.logLength--;
}
我如何返回/获取价值正在 stackPop 功能弹出?我不想改变实现,但如果有这使相同的范围内实施尽可能,那么我会AP preciate一个好办法。其它方法也是可接受的。
How do I return/get the value being popped off in stackPop function? I do not want to change the implementation but if there is a good way which keeps the implementation same to the extent as much as possible, then I would appreciate that. Other approaches are also acceptable.
推荐答案
我认为你能做的最好的是返回一个指向弹出数据(以无效*
因为这是对你最好可以在C为通用的功能一样):
I think the best you could do is to return a pointer to popped data (as a void*
since that's about the best you can do in C for a 'generic' function):
void* stackPop(Stack *s, void *elemAddr){
void *source = (char *)s.elems + (s.logLength-1)*s.elemSize;
memcpy(elemAddr,source,s.elemSize);
s.logLength--;
return elemAddr;
}
请注意,调用者仍然需要提供存储器和数据弹出到的地址;如果你想编辑你可避免由具有功能的malloc()
内存
Note that the caller still needs to provide the memory and the address to pop the data into; if you want ed you could avoid that by having the function malloc()
the memory:
void* stackPop(Stack *s){
void *source = (char *)s.elems + (s.logLength-1)*s.elemSize;
void *elemAddr = malloc(s.elemSize);
// if (!elemAddr) handle_error();
memcpy(elemAddr,source,s.elemSize);
s.logLength--;
return elemAddr;
}
当然,这需要调用者免费()
它时,它不再需要,并增加了需要处理的内存不足情况的轻微的并发症。
Of course that would require the caller to free()
it when it is no longer needed, and adds the minor complication of needing to handle the out of memory situation.
这篇关于用C通用堆栈的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!