【问题标题】:Generic Stacks in CC 中的通用堆栈
【发布时间】:2012-09-18 20:32:42
【问题描述】:

我正在用 C 实现通用堆栈,但我在 stackPop 方法中遇到了问题。我的结构如下:

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

【问题讨论】:

  • stackPop. 中简单地返回一个值会更有意义。为什么实现必须保持不变?
  • @Vulcan 他可能指的是堆栈的实现,而不是函数。
  • 那很好,但我考虑了一段时间,如果你觉得改变实现并没有改变这个概念,那么你能提供一个更好的方法吗?
  • 我希望我的堆栈实现尽可能相同。
  • 是的,我认为将其设为镜像 stackPush 没有问题。目前的方法有什么问题?

标签: c generics stack


【解决方案1】:

我认为你能做的最好的事情是返回一个指向弹出数据的指针(作为void*,因为这是你在 C 中为“通用”函数所做的最好的事情):

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;
}

注意调用者仍然需要提供内存和地址来弹出数据;如果你想要 ed,你可以通过使用函数 malloc() 来避免这种情况:

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()它,并增加了需要处理内存不足情况的小麻烦。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-07-02
    • 2013-10-13
    • 2013-07-06
    • 2013-09-25
    • 1970-01-01
    • 1970-01-01
    • 2012-01-18
    • 2012-10-30
    相关资源
    最近更新 更多