简体   繁体   English

C99中的可变函数要重新分配几个数组?

[英]Variadic function in C99 to deallocate several arrays?

Currently, I have a very simple function to deallocate array of doubles in my program: 当前,我有一个非常简单的函数来在程序中释放双精度数组:

void deallocate(double** array)
{
    free(*array);
}

I would like this function to be variadic in order to take several arrays, and free them one after another. 我希望此函数可变,以便采用多个数组,并一个接一个地释放它们。 I've never written a variadic function, and as there may exist tricks with pointers I would like to know how to do that. 我从未写过可变参数函数,由于可能存在一些使用指针的技巧,我想知道如何做到这一点。

Don't do this with a variadic function, this concept should be retired. 不要通过可变函数来执行此操作,这个概念应该被淘汰。 In particular it makes no sense at all for something that is to receive arguments of all the same type, void* . 特别是对于要接收所有相同类型的参数void*东西根本没有任何意义。

Just have a simple function, first that receives an array of pointers 只是有一个简单的函数,首先接收一个指针数组

void free_arrays(void* a[]) {
  for (size_t i = 0; a[i]; ++i) free(a[i]);
}

Then you can wrap that with a macro like that 然后可以用这样的宏将其包装

#define FREE_ARRAYS(...) free_arrays((void*[]){ __VA_ARGS__, 0 })

This supposes that none of your pointers is already 0 , since the processing would stop at that point. 假设您的所有指针都不是0 ,因为处理将在该点停止。

If you'd have a need to have that working even if some of the pointers are 0 , you'd have to pass the number of elements as a first parameter to your function. 如果即使某些指针为0 ,也需要使它工作,则必须将元素数量作为第一个参数传递给函数。 This is a bit tedious but can be determined in the macro, too. 这有点乏味,但是也可以在宏中确定。

void free_arrays0(size_t n, void* a[]) {
  for (size_t i = 0; i < n; ++i) free(a[i]);
}

#define FREE_ARRAYS0(...)                                    \
  free_arrays(                                               \
              sizeof((void*[]){ __VA_ARGS__})/sizeof(void*), \
              (void*[]){ __VA_ARGS__}                        \
             )

You can do it like this: 您可以这样做:

void deallocate(double *p, ...)
{
    va_list ap;

    va_start(ap, p);
    do {
        free(p);
        p = va_arg(ap, double *);
    } while (p);
    va_end(ap);
}

Call as deallocate(p1, p2, p3, (double *)NULL) . 调用为deallocate(p1, p2, p3, (double *)NULL) You need the NULL (or some other value) as a sentinel to signal the end of the argument list; 您需要将NULL (或其他某个值)作为标记来表示参数列表的结尾; none of the other pointers should be NULL or the loop will stop prematurely. 其他指针都不应该为NULL否则循环将过早停止。

I'm not saying that this is a good idea, though: varargs functions have their use cases, but they're error-prone with pointers because some implicit conversions don't take place (because the compiler doesn't know the type of the arguments beyond the first). 我并不是说这是个好主意:varargs函数有其用例,但它们很容易出现指针错误,因为某些隐式转换不会发生(因为编译器不知道超出第一个的论点)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM