我正在为一个相当古老的软件包 (NWChem) 开发一个模块,我不确定从一对相当常用的函数调用中创建一个函数的最佳方法。主包内有一组用于操作运行时数据库的函数。我经常一起使用的一对是 rtdb_get_info
和 rtdb_get
来提取有关数据库中一个值的内容的信息并获取实际值。这些函数的 header 是:
extern int rtdb_get_info(const int, const char *, int *, int *, char [26]);
extern int rtdb_get(const int, const char *, const int, const int, void *);
调用它们的方式是执行如下操作(忽略返回值):
int nelem, ma_type;
char date[26];
rtdb_get_info(rtdb, "nameofrtdbvalue", &ma_type, &nelem, date)
rtdb_get(rtdb, "nameofrtdbvalue", ma_type, array)
其中 rtdb 是一个在其他地方设置的整数,指定您要访问的数据库,而 array 是您要存储“nameofrtdbvalue”中存储的值的数组。在某些情况下,您可能会在进行实际的 rtdb_get
调用之前array = malloc(nelem * sizeof *array)
。
目前,我正在使用以下函数来调用这对:
void rtdb_pull(int rtdb, const char *name, void *array) {
int ma_type;
int nelem;
char date[26];
if (rtdb_get_info(rtdb, name, &ma_type, &nelem, date)) {
if (rtdb_get(rtdb, name, ma_type, nelem, array))
printf("Retrieved %s from rtdb.\n", name);
else
printf("%s is in rtdb, but not retrievable.\n", name);
}
else
printf("Couldn't get info on %s from rtdb.\n", name);
}
这是我将分配内容并调用 rtdb_pull
的示例方法。在本例中,我将从数据库中提取一个包含 3*npoints double 的数组,然后将它们传递给对数组 coords 执行某些操作的其他函数。这通常会发生在我需要重新分配内存的循环中。
double *coords=malloc(sizeof *coords);
int npoints, rtdb;
int i, nloops;
char buf[32];
get_rtdb(&rtdb); //Just something that gets the integer for the runtime database
for (i=0;i<nloops;i++) {
get_npoints(&npoints);
coords=realloc(coords,npoints * sizeof *coords);
rtdb_pull(rtdb,"geometryname",coords);
use_coords(coords);
}
free(coords);
rtdb_pull
是我在学习 c 时编写的第一个函数,我注意到我调用它的次数越多,出现段错误的可能性就越大,所以我想重写它,但我不确定最好的方法。似乎调用它会导致内存泄漏,但我不确定为什么。也许这与我将指向为 double 组分配的内存的指针传递给 void * 的事实有关?如果是这样,我不确定如何解决这个问题(并且不断调用这对函数真的很烦人)。
有什么想法或建议吗?
最佳答案
使用 void* 并没有错,它们可以在您需要时像通用类型一样工作,看起来这就是您要找的,对吧?
int myfunc(void* data, int op)
{
double *mycoords;
if(op == 1) // a way to control the real type
mycoords = (double*) data;
//...
return 0;
}
在函数内部,您可以强制转换 (void*) 或将 (void*) 转换为您需要的类型。
另一种方法是编写一个带有可变参数列表的函数,一个来自 stdarg 手册页的示例:
#include <stdio.h>
#include <stdarg.h>
void
foo(char *fmt, ...)
{
va_list ap;
int d;
char c, *s;
va_start(ap, fmt);
while (*fmt)
switch (*fmt++) {
case 's': /* string */
s = va_arg(ap, char *);
printf("string %s\n", s);
break;
case 'd': /* int */
d = va_arg(ap, int);
printf("int %d\n", d);
break;
case 'c': /* char */
/* need a cast here since va_arg only
takes fully promoted types */
c = (char) va_arg(ap, int);
printf("char %c\n", c);
break;
}
va_end(ap);
}
关于c - 如何制作可以接收不同类型参数的 c 函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20999469/