2种免费通话方式——有区别吗?

2 Ways of calling free - is there a difference?

在堆上分配内存后调用 free 的两种变体有区别吗:

// variant 1
int* p1 = (int*) malloc(sizeof(int)*4);
free(p1);

//variant 2
int* p2 = (int*) malloc(sizeof(int)*4);
free(*p2);
*p2 = NULL;

是的,有区别。

变体 2 无效。 free 需要先前由 malloccallocrealloc 返回的指针。 *p2 是分配的 space 中的第一个 int 。正如 man free 所说,因此发生了未定义的行为(针对此特定情况调整了报价):

free() function frees the memory space pointed to by [p1], which must have been returned by a previous call to malloc(), calloc(), or realloc(). Otherwise, [...] undefined behavior occurs.


备注:

  • don't cast the result of malloc

是的。 free(*p2) 无效。

free 释放指定地址的内存。考虑一下:p1 的计算结果是什么?它的值是 malloc 返回的指针 - 因此 p1 求值为指向 malloc 分配的内存的指针。

*p2 的计算结果是什么?它的值是存储在p2地址的整数。这可以是任何东西,而且它不太可能是一个有效的指针。因此 free 将尝试释放一个无效的内存地址,如果你幸运的话,你会得到一个段错误。

是的,有区别。第一种方法,调用指向由 malloc 分配的内存的指针是正确的。第二,调用这样一个指针的取消引用,试图释放一些任意内存地址(值保存在指针指向的 value 中),这是错误的。

free(p1);

这是有效的,因为您将内存分配给 p1,然后分配给 free,因此没问题。

free(*p2);

它不太可能有效,因为 *p2 可能是也可能不是有效指针(需要分配内存)。

在未使用 malloc 或类似方法分配内存的指针上使用 free() 会导致错误