C语言 在特殊情况下使用 void 是否安全?仍然未定义的行为?



我想创建一个函数来释放指针指向的内存并将此指针分配给 NULL。所以我必须将参数声明为void**(间接指针(,我知道void*可以安全地转换指针,并且使用void**是未定义的行为。但我认为在这种情况下应该没有问题。此函数是否可以安全地释放malloc()分配的任何内存,而不会产生未定义的行为? 请黑客帮助或建议更好的方法。

C 代码:

#include <stdio.h>
#include <stdlib.h>
// If I use safeFree(&mac_arr); ,
// it will warn "Incompatible pointer types passing ' int **' to parameter of type ' void **'"
// So I used #define, don't care about this.
#define SAFE_FREE(p) safeFree((void **)&(p))
void safeFree(void ** ptr);
int main(void) {
int *mac_arr = malloc(sizeof *mac_arr);
SAFE_FREE(mac_arr);
return 0;
}
void safeFree(void ** ptr){
if (ptr != NULL && *ptr != NULL) {
free(*ptr);
*ptr = NULL;
}
}

此类代码的行为不是由 C 标准定义的。

mainmac_arr是一个int *safeFree接收的参数是指向void *的指针。但int *void *不是 C 标准定义的兼容类型。它们可能具有不同的大小、对齐要求和表示形式。因此,将mac_arr的地址从int **转换为void **并将*ptr用于类型void *的左值是不便携的。

它可能在许多 C 实现中"工作"。

您正在考虑的SAFE_FREE宏不是指针问题的好方法。虽然它将指向对象的当前指针设置为 null,但它无法影响指向同一对象的其他指针,例如链表中的链接或其他数据结构中的链接。

(它也不需要测试*ptr != NULLfree被指定为在传递 null 指针时不执行任何操作,因此您只会在已执行的测试上加倍。

指针类型int **void **不兼容。类型转换只是掩盖了不兼容性。

您可以定义:

#define SAFE_FREE(p) ((void)(free(p), (p) = NULL))

最新更新