用C通用堆栈 [英] Generic Stacks in C

查看:167
本文介绍了用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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆