为什么我们不必在C中释放结构的嵌入指针

时间:2011-12-06 16:43:39

标签: c

我见过以下code

/* 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

1 个答案:

答案 0 :(得分:6)

实际上你必须在某处释放mStack ,否则你会泄漏内存。如果StackDestroy没有为您执行此操作,则必须稍后自行完成。

在设计分配和释放内容的API时,请考虑以下几点:

  • 客户端是否分配了对象?也许他也应该释放它。是否有可能传递了一个未通过malloc获得的对象?
  • 客户端可以在对象消亡之后对对象做有用的事情吗?

在你的情况下,客户端甚至不知道mStack的存在(技术上你可以使用不透明的对象),所以,因为分配它,你也应该释放它。