2012-09-27 28 views
4

我在C中實現通用堆棧,並且在stackPop方法中遇到問題。我的結構如下:C中的通用堆棧C

「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功能?我不想改變實現,但是如果有一種儘可能保持實現的程度相同的好方法,那麼我會很感激。其他方法也是可以接受的。

+0

簡單地在'stackPop'中返回一個值會更有意義。爲什麼實現必須保持不變? – Vulcan

+0

@Vulcan他可能意味着堆棧的實現,而不是函數。 – elyashiv

+0

這會很好,但我想了一會兒,如果你覺得這個概念不會因爲改變實現而改變,那麼你能否給我一個更好的方法? –

回答

6

我認爲你能做的最好的是返回一個指針彈出的數據(作爲void*因爲這是你可以下一個「通用」的功能做到最好):

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()內存:

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()它,當不再需要它,並增加了需要處理的輕微併發症內存不足的情況。