我想创建一个函数来释放指针指向的内存并将此指针分配给 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 标准定义的。
在main
,mac_arr
是一个int *
。safeFree
接收的参数是指向void *
的指针。但int *
和void *
不是 C 标准定义的兼容类型。它们可能具有不同的大小、对齐要求和表示形式。因此,将mac_arr
的地址从int **
转换为void **
并将*ptr
用于类型void *
的左值是不便携的。
它可能在许多 C 实现中"工作"。
您正在考虑的SAFE_FREE
宏不是指针问题的好方法。虽然它将指向对象的当前指针设置为 null,但它无法影响指向同一对象的其他指针,例如链表中的链接或其他数据结构中的链接。
(它也不需要测试*ptr != NULL
。free
被指定为在传递 null 指针时不执行任何操作,因此您只会在已执行的测试上加倍。
指针类型int **
和void **
不兼容。类型转换只是掩盖了不兼容性。
您可以定义:
#define SAFE_FREE(p) ((void)(free(p), (p) = NULL))