为什么我可以两次释放内存,但在不同的情况下却不能?

Why can I free memory twice, but can't in different situations?

这是我目前的代码。

int main() {
    double *t, *k;
    Item *a = calloc(1, sizeof(Item));
    a->w = malloc(sizeof(double));
    t = a->w;
    k = t;
    free(a->w);
    free(a);
    free(k);
    return 0;
}

在这个例子中,我能够编译 运行 而没有出现任何明显的错误。但是,如果我在释放结构 a 之前释放指针 k,那么我会收到双重 free/heap 损坏错误。

free(a->w);
free(k);
free(a);

此外,如果我这样做,我会收到同样的错误:

free(k);
free(a->w);
free(a);

为什么在结构被释放后我可以释放指针 k 而没有任何显式错误,但是我不能释放内存 k 指向两次直到结构 a 被释放?

这是 Undefined behavior. This means anything can happen, such as appearing to work, crashing immediately, crashing at some point later, or strange unexpected behavior, or the often mentioned nasal demons 的示例。

来自man page

free() frees the memory space pointed to by ptr, which must have been returned by a previous call to malloc(), calloc() or realloc(). Otherwise, or if free(ptr) has already been called before, undefined behaviour occurs. If ptr is NULL, no operation is performed.

因此可能会触发 double-free 错误,但不是必需的。