2011-12-06 38 views
1

我看到下面code爲什麼我們沒有釋放一個結構的嵌入指針用C

/* stack.c */ 
typedef struct Stack *StackPtr; 

struct Stack 
{ 
    int *mStack; 
    int mCurSize; 
}; 

StackPtr StackCreate() 
{ 
    return (StackPtr) calloc(sizeof(struct Stack), 1); 
} 

void StackDestroy(StackPtr stack) 
{ 
    if (stack) 
    { 
     free(stack); 
    } 
} 

void StackPush(StackPtr stack, int val) 
{ 
    if (! stack) 
     return; 

    if (stack->mStack) 
    { 
     int newsize = stack->mCurSize + 1; 
     int *newptr = realloc(stack->mStack, sizeof(struct Stack)*newsize); 
     if (newptr) 
     { 
      stack->mStack = newptr; 
      stack->mStack[newsize-1] = val; 
      stack->mCurSize = newsize; 
     } 
    } 
    else 
    { 
     stack->mStack = malloc(sizeof(struct Stack)); 
     if (stack->mStack) 
     { 
      stack->mStack[0] = val; 
      stack->mCurSize = 1; 
     } 
    } 
} 

int StackPop(StackPtr stack) 
{ 
    if (! StackIsEmpty(stack)) 
    { 
     return stack->mStack[--stack->mCurSize]; 
    } 
    return 0; 
} 


void StackDestroyMyWay(StackPtr stack) // This is my understanding 
{ 
    if (stack) 
    { 
     if (stack->mStack) 
      free(stack->mStack); 
     free(stack); 
    } 
} 

int StackIsEmpty(const StackPtr stack) 
{ 
    return stack == NULL || stack->mCurSize == 0; 
} 

/* main.c */ 
int main(int argc, char *argv[]) 
{ 
    /* Create a new stack */ 
    StackPtr stack = StackCreate(); 
    int val; 

    /* push and pop a value to the stack */ 
    printf("Empty: %d\n", StackIsEmpty(stack)); 
    StackPush(stack, 10); 
    printf("Empty: %d\n", StackIsEmpty(stack)); 
    val = StackPop(stack); 
    printf("Popped off: %d\n", val); 
    printf("Empty: %d\n", StackIsEmpty(stack)); 

    /* clean up the stack */ 
    StackDestroy(stack); 
    return 0; 
} 

問題>我假定原來StackDestory正確實現,但我不知道明白爲什麼我們不必明確地釋放stack->mStack

+0

我認爲你的方式是正確的方法。鑑於你向我們展示了什麼,除非明確地釋放mStack纔會泄漏。 –

+0

我認爲你必須和原始實現有內存泄漏。除非它在代碼中某處不顯示:) – 2011-12-06 16:47:49

+1

我認爲'StackDestroyMyWay()'也是正確的。但請注意,[您不必在'free()'](http://stackoverflow.com/q/1912325/10077)之前檢查null。所以你可以說,'if(stack){free(stack-> mStack);自由(堆);}'。 –

回答

6

其實你必須釋放mStack地方否則你會泄漏內存。如果StackDestroy不適合你,那麼你必須在以後自己做。

當設計一個分配和釋放的東西思考的幾件事的API:

  • 沒有客戶端分配的對象?也許他也應該釋放它。他有可能傳遞了一個沒有通過malloc獲得的物體嗎?
  • 客戶端能否在對象消亡之後對對象做有用的事情?

在你的情況下,客戶甚至不知道的mStack存在(在技術上你可以使用不透明的物體),所以,既然你分配它,你也應該釋放它。

+0

所以你認爲函數'StackDestroyMyWay'是否正確實現? – q0987

+0

@ q0987:我想每個人都這樣做,除非有一些細節你不知道...... – 2011-12-06 16:48:30

相關問題