2016-11-14 67 views
1

我想構建一個通用堆棧,但我的彈出方法似乎是錯誤的,因爲它打印數字從100到1和1倍。 如果我改變彈出式方法向此溶液:Generic Stacks in C它彈出到64,然後就64倍0通用堆棧停止彈出的值

結構:

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

C-源文件:

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

回答

1

在GenStackPop函數的第二個的memcpy調用似乎是多餘的和做什麼,但揍的第一個元素:

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

好吧,我得到的編譯器警告在需要時的void *大小是不知道。這occurrs在:

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

爲你s->elems和流行使用+

將結構聲明中的void *elems;更改爲char *elems;,它工作正常。

+0

OP正在使用編譯器擴展。 – 2501

+0

@ 2501,這個擴展等同於這些操作'void *'到'char *'? –

+0

https://gcc.gnu.org/onlinedocs/gcc/Pointer-Arith.html – 2501