c - 如何制作可以接收不同类型参数的 c 函数?

标签 c arrays pointers malloc realloc

我正在为一个相当古老的软件包 (NWChem) 开发一个模块,我不确定从一对相当常用的函数调用中创建一个函数的最佳方法。主包内有一组用于操作运行时数据库的函数。我经常一起使用的一对是 rtdb_get_infortdb_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/

相关文章:

GCC 不同部分中的常量指针

c - GCC优化后如何丢弃未使用的函数

javascript - 如何从对象数组中获取从未出现在特定属性中的值

c - 取消引用二维的名称与名称相同。那么取消引用有什么作用呢?

c++ - 取消引用 unsigned char 指针并将其值存储到字符串中

php - array_key_exists 运行不正常

c - K&R快速排序问题

c++ - 如何在不更改原始 tm 结构的情况下使用 mktime()?

c - 请解释这段代码在做什么(someChar - 48)

c - C指针怎么可以这样作为函数的形参呢?