通用堆栈会停止弹出值

时间:2016-11-14 13:27:46

标签: c generics

我正在尝试构建一个通用堆栈,但我的pop方法似乎错了,因为它打印的数字从100到1和1加倍。 如果我将pop方法更改为此解决方案:Generic Stacks in C它弹出为64,然后只弹出64次0.

结构:

typedef struct {
    void *elems;
    int elemSize;
    int logLength;
    int allocLength;
    void (*freefn)(void*);
} genStack;

C-Source文件:

#include "genstacklib.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

void GenStackNew(genStack *s, int elemSize, void(*freefn)(void *)) {
    s->elemSize = elemSize;
    s->elems = malloc(4 * s->elemSize);
    if (s->elems == NULL) {
        perror("\n\nError: ");
    }
    s->allocLength = 4 * s->elemSize;
    s->logLength = 0;
    s->freefn = freefn;
}

void GenStackDispose(genStack *s) {
    if (s->elems == NULL) {
        printf("\n\nStack is not initialized!\n\n");
        return;
    }
    /*if (s->freefn != NULL) {
        int n = 0;
        while (s->logLength != 0) {
            freefn(s->elems + n * s->elemSize);
            n++;
        }
    }*/
    free(s->elems);
}

bool GenStackEmpty(const genStack *s) {
    if (s->logLength == 0) {
        return true;
    } else {
        return false;
    }
}

void GenStackPush(genStack *s, const void *elemAddr) {
    if (s->elems == NULL) {
        printf("\n\nStack not initialized!\n\n");
        return;
    }
    if (s->allocLength == s->logLength * s->elemSize) {
        s->allocLength = 2*s->allocLength;
        s->elems = realloc(s->elems, s->allocLength*s->elemSize);
    }
    memcpy(s->elems+s->logLength*s->elemSize,elemAddr,s->elemSize);
    s->logLength++;
}

void GenStackPop(genStack *s, void *elemAddr) {
    void *source = s->elems + (s->logLength-1)*s->elemSize;
    memcpy(elemAddr,source,s->elemSize);
    memcpy(s->elems,source,s->elemSize);
    s->logLength--;
    //memcpy((char*)s->elems+(s->logLength-1)*s->elemSize,elemAddr,s->elemSize);
}

测试堆栈(应该将数字从0推到100并在之后弹出):

int main(int argc, char *argv[]) {

    int val;
    genStack IntegerStack;

    GenStackNew(&IntegerStack, sizeof(int), NULL);
    for (val = 0; val < 100; val++) {
        GenStackPush(&IntegerStack, &val);
        printf("Pushed: %d\n",val);
    }

    while(!GenStackEmpty(&IntegerStack)){
        GenStackPop(&IntegerStack, &val);
        printf("Popped: %d\n",val);
    }

    GenStackDispose(&IntegerStack);
}

2 个答案:

答案 0 :(得分:1)

GenStackPop函数中的第二个memcpy调用似乎是多余的,只会破坏第一个元素:

memcpy(s->elems,source,s->elemSize);

答案 1 :(得分:1)

好吧,我得到编译器警告,在需要时不知道'<'的大小。这发生在:

void *

memcpy(s->elems+s->logLength*s->elemSize,elemAddr,s->elemSize); 和pop。

上使用+

将结构声明中的s->elems更改为void *elems;,它可以正常工作。