释放可变参数函数中的所有参数

use*_*815 -2 c free variadic-functions

我的使命是创建一个函数,该函数接收可变数量的参数并为任何类型的参数释放所有参数。我尝试使用可变参数函数来做到这一点,但问题是我不知道参数的类型。

关于如何做有什么建议吗?

Jon*_*ler 5

将每个指针视为void *; 将其传递给free()

void free_anything(void *arg1, ...)
{
    va_list args;
    void *vp;
    free(arg1);
    va_start(args, arg1);
    while ((vp = va_arg(args, void *)) != 0)
        free(vp);
    va_end(args);
}
Run Code Online (Sandbox Code Playgroud)

调用示例:

free_anything(p1, p2, p3, p4, (void *)0);
Run Code Online (Sandbox Code Playgroud)

另一种设计传递要释放的参数数量作为第一个参数:

free_everything(4, p1, p2, p3, p4);
Run Code Online (Sandbox Code Playgroud)

替代函数的实现也很简单:

void free_anything(size_t n, ...)
{
    va_list args;
    va_start(args, n);
    for (size_t i = 0; i < n; i++)
    {
        void *vp = va_arg(args, void *);
        free(vp);
    }
    va_end(args);
}
Run Code Online (Sandbox Code Playgroud)

请注意,带有计数器 ( ) 的设计free_everything()可能更好;您可以编写一个函数来清理函数中的多个分配:

void memory_intensive(int size)
{
    int *p1 = malloc(size * sizeof(*p1));
    char *p2 = malloc(size * 32);
    struct wotnot *p3 = malloc(sizeof(*p3));
    struct onemore *p4 = malloc(size * sizeof(*p4));
    struct later *p5 = 0;
    struct muchlater *p6 = 0;

    if (some_condition(p1, p3, size))
    {
        p5 = malloc(size * sizeof(*p5));
        ...
    }
    if (another_condition(p2, p4, size))
    {
        p6 = malloc(size * sizeof(*p6));
        ...
    }

    free_everything(6, p1, p2, p3, p4, p5, p6);
}
Run Code Online (Sandbox Code Playgroud)

这将释放单个函数调用中所有已分配的内存,无论是否p5p6分配(或者是否有任何其他分配失败)。然而,这正在突破极限。然而,在这样的设计中,至关重要的是不要停在第一个空指针处……以防万一列表中后面有非空指针。

  • 您必须使用“(void*)0”,因为“NULL”不能保证是一个指针值,它同样可能只是“0”,在这种情况下,当“int”和“void*”时您会遇到麻烦` 有不同的宽度。欲了解更多信息,请参阅http://gustedt.wordpress.com/2010/11/07/dont-use-null/ (2认同)