在特殊情况下使用void **是否安全?还是不确定的行为?

Tre*_*one 0 c malloc

我想创建一个函数来释放指针所指向的内存,并将该指针分配为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;
    }
}
Run Code Online (Sandbox Code Playgroud)

Eri*_*hil 5

C代码未定义此类代码的行为。

在中mainmac_arr是一个int *。参数safeFreereceive是指向的指针void *。但是int *void *不是C标准定义的兼容类型。它们可能具有不同的大小,对齐要求和表示形式。所以转换的地址mac_arr来自int **void **使用*ptr类型的左值void *是不可移植。

它可能在许多C实现中“起作用”。

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

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