目前,我有一个非常简单的函数可以在我的程序中释放双精度数组:
void deallocate(double** array)
{
free(*array);
}
我希望这个函数是可变的,以便获取多个数组,并一个接一个地释放它们。我从来没有写过可变参数函数,因为可能存在指针技巧,我想知道如何做到这一点。
目前,我有一个非常简单的函数可以在我的程序中释放双精度数组:
void deallocate(double** array)
{
free(*array);
}
我希望这个函数是可变的,以便获取多个数组,并一个接一个地释放它们。我从来没有写过可变参数函数,因为可能存在指针技巧,我想知道如何做到这一点。
不要用可变参数函数来做这个,这个概念应该被淘汰。特别是对于要接收所有相同类型的参数的东西来说根本没有意义,void*
.
只要有一个简单的函数,首先接收一个指针数组
void free_arrays(void* a[]) {
for (size_t i = 0; a[i]; ++i) free(a[i]);
}
然后你可以用这样的宏包装它
#define FREE_ARRAYS(...) free_arrays((void*[]){ __VA_ARGS__, 0 })
这假设您的任何指针都不是0
,因为处理将在该点停止。
如果即使某些指针是0
,你也需要让它工作,你必须将元素的数量作为第一个参数传递给你的函数。这有点乏味,但也可以在宏中确定。
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__} \
)
你可以这样做:
void deallocate(double *p, ...)
{
va_list ap;
va_start(ap, p);
do {
free(p);
p = va_arg(ap, double *);
} while (p);
va_end(ap);
}
调用为deallocate(p1, p2, p3, (double *)NULL)
. 您需要将NULL
(或其他值)作为标记来表示参数列表的结束;其他指针都不应该是NULL
,否则循环将过早停止。
不过,我并不是说这是一个好主意:可变参数函数有它们的用例,但是它们很容易使用指针出错,因为不会发生一些隐式转换(因为编译器不知道第一个之外的论点)。