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"...

我正在用 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 函数中返回/获取弹出的值?我不想更改实现,但如果有一种好的方法可以尽可能地保持实现相同,那么我将不胜感激.其他方法也是可以接受的.

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.

推荐答案

我认为你能做的最好的事情是返回一个指向弹出数据的指针(作为 void* 因为那是你最好的可以在 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;
}

当然,这需要调用者在不再需要它时 free() 它,并增加了需要处理内存不足情况的次要并发症.

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.

阅读全文

相关推荐

最新文章