2011-12-06 39 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

相关问题