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

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

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.

这篇关于C 中的通用堆栈的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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