通用堆栈不会推送或弹出值

时间:2014-08-09 15:06:43

标签: c generics

我试图在C中实现通用堆栈,但我无法打印我推送的值。这是代码

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <memory.h>

typedef struct{
    void *elems;
    int sizeOfElems;
    int allocated;
    int lenght;
}stack;

void allocate_stack(stack *s, int sizeOfElements){
    assert(sizeOfElements > 0);
    s->sizeOfElems = sizeOfElements;
    s->allocated = 2;
    s->lenght = 2;
    s->elems = malloc(sizeOfElements * s->allocated);
}

void deallocate_stack(stack *s){
    free(s->elems);
}

void push_elem(stack *s, void *elem){
    s->lenght += 1;
    if(s->allocated == s->lenght){
        realloc(s, s->lenght * s->sizeOfElems);
        s->lenght *= 2;
    }
     void *target = (char *)s->elems + s->lenght * s->sizeOfElems;
     memcpy(target, elem, s->sizeOfElems);
}
void pop_elem(stack *s, void *elemAddr){
    void *source = (char *)s->elems + (s->lenght-1) * s->sizeOfElems;
    memcpy(elemAddr, source, s->sizeOfElems);
    s->lenght -=1;
}
int main(){
    stack s;
    allocate_stack(&s, 1);
    char a = 'a';
    push_elem(&s, &a);
    char *elem = NULL;
    pop_elem(&s, elem);
    printf("%s", elem);
    deallocate_stack(&s);
    return 0;
}

问题是我在运行程序时没有得到任何东西,只需按返回关闭窗口即可。我使用GCC工具包在Linux上编程。

2 个答案:

答案 0 :(得分:2)

您缺少堆栈结构的分配。执行allocate_stack时,必须先调用allocate来创建堆栈对象,然后再将其分配给它。例如,您传入的s为null,您开始尝试将值分配给它的各个字段。这是未定义的行为,可能是您的程序无法正常工作的原因。

尝试更改allocate_stack函数的签名以返回堆栈指针,然后第一步应该是malloc(sizeof struct stack)。你应该返回你从malloc获得的指针,并将其分配给s。

编辑:除非你希望堆栈在堆栈上,否则就像普通变量一样分配它。

答案 1 :(得分:0)

在你的push_elem中:

    s->lenght += 1;
    if(s->allocated == s->lenght){
        realloc(s, s->lenght * s->sizeOfElems);
        s->lenght *= 2;
    }

如果你用完了,你似乎正在尝试重新分配空间,但是你分配的默认值2将保持不变,你可能应该这样做:

    if (s->allocated < s->lenght) {
        realloc(s->elems, ....)
        //Increase both allocated and length to represent the current state of the stack
    }

请注意,在realloc()调用中,您传递的是s,它位于堆栈中,这将无法执行您想要的操作: http://pubs.opengroup.org/onlinepubs/7908799/xsh/realloc.html 根据你的结构,你应该通过         S-&GT; elems的

此外,在调用pop_elem之前,您要为elem分配NULL。在pop_elem中,这是你尝试做memcpy()的地方。为此,您必须分配内存:http://pubs.opengroup.org/onlinepubs/009695399/functions/memcpy.html