使用void*,void**和可变参数函数

Gam*_*Gam 5 c variadic-functions void-pointers

我想编写一个可以释放尽可能多的指针的函数.所以我有这个:

void    myfree(size_t n, ...)
{
    void    **del;
    va_list ap;

    va_start(ap, n);
    while (n > 0)
    {
        del = va_arg(ap, void **);
        free(*del);
        *del = NULL;
        --n;
    }
    va_end(ap);
}
Run Code Online (Sandbox Code Playgroud)

我称之为:

char *one = malloc(x);
sometype_t *two = malloc(x);
myfree(2, &one, &two);
Run Code Online (Sandbox Code Playgroud)

我假设one并且two现在指向NULL.它似乎有效,但我仍然有点担心.我做了一些研究,void**但我不确定我的功能是否真的有效(UB你在那里吗?)


在我的研究和测试中,我尝试了一些我不太懂的东西.

假设我们有这个功能

void    f(void **ptr)
{
} 
Run Code Online (Sandbox Code Playgroud)

如果我这样称呼它

int *intptr = NULL;
f(&intptr);
Run Code Online (Sandbox Code Playgroud)

我收到编译器警告: warning: incompatible pointer types passing 'int **' to parameter of type 'void **'

所以我尝试了这个

int *intptr = NULL;
f( & ((void *)intptr) );
Run Code Online (Sandbox Code Playgroud)

编译错误: error: cannot take the address of an rvalue of type 'void *'

但如果我这样做

void *voidptr = NULL;
f(&voidptr); // I can take the address of a void pointer right ?
Run Code Online (Sandbox Code Playgroud)

实际上void*,void**与他们的转换/演员对我来说仍然不清楚.这就是为什么我担心上面发布的myfree().如果你们有任何解释我会很感激:)

dbu*_*ush 1

C 标准允许与 a 相互转换void *,但不允许 a void **。在大多数实现中,您可能会遇到它们应该具有相同的大小,但不能保证这一点。所以这是未定义的行为。

这是宏函数最有意义的情况之一,尽管您一次只能释放一个指针:

#define myfree(ptr) do { free(ptr); ptr = NULL; } while (0)
Run Code Online (Sandbox Code Playgroud)