2012-09-27 4 views
4

C에서 generic 스택을 구현 중이며 stackPop 메서드에서 문제가 있습니다.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

나는 (즉, 당신이 '일반적인'기능을 위해 C에서 할 수있는 최선 관하여부터 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()에게 메모리를함으로써 그것을 피할 수 :

이 더 이상 필요하지 않을 때 free()에 호출을 필요로하지 않으며, 처리 할 필요의 작은 합병증을 추가 할 물론
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; 
} 

메모리 부족 상황.