Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
void指针和ffcall库_C_Pointers_Void_Memory Corruption - Fatal编程技术网

void指针和ffcall库

void指针和ffcall库,c,pointers,void,memory-corruption,C,Pointers,Void,Memory Corruption,我正在使用ffcall(特别是ffcall的avcall包)库来动态地将参数推送到可变函数。i、 我们有 int blah (char *a, int b, double c, ...); 我们想用从用户那里获取的值调用这个函数。为此,我们创建函数的avcall版本: int av_blah (char *a, int b, double c, char **values, int num_of_values) { av_alist alist; int i, ret;

我正在使用ffcall(特别是ffcall的avcall包)库来动态地将参数推送到可变函数。i、 我们有

int blah (char *a, int b, double c, ...);
我们想用从用户那里获取的值调用这个函数。为此,我们创建函数的avcall版本:

int av_blah (char *a, int b, double c, char **values, int num_of_values)
{
    av_alist alist;
    int i, ret;
    av_start_int (alist, &blah, &ret); //let it know which function
    av_ptr (alist, char*, a); // push values onto stack starting from left
    av_int (alist, b);
    av_double (alist, c);
    for (i=0;i<num_of_values;i++)
    {
        // do what you want with values and add to stack
    }
    av_call (alist);  //call blah()

    return (ret);
}
它是这样使用的:

struct some_struct a;
struct another_struct **b = fill_with_stuff ();

char name[64];
int num;
while (read_row (&a, b, name, &num)==0)
{
    printf ("name=%s, num=%d\n", name, num);
}
但是我想使用avcall从这个函数中捕获一定数量的值,我事先不知道这些信息。所以我想我应该创建一个void指针数组,然后根据类型创建malloc空间:

char printf_string[64]=""; //need to build printf string inside av_read_row()
void **vals = Calloc (n+1, sizeof (void*)); //wrapper
while (av_read_row (&a, b, vals, n, printf_string) == 0)
{
    // vals should now hold the values i want
    av_printf (printf_string, vals, n);  //get nonsense output from this
    // free the mallocs which each vals[i] is pointing to
    void **ptrs = vals;
    while (*ptrs) {
       free (*ptrs);  //seg faults on first free() ?
       *ptrs=NULL;
       ptrs++;
    }
    //reset printf_string
    printf_string[0]='\0';
    printf ("\n");
}
av\u read\u row
只是:

int av_read_row (struct some_struct *a, struct another_struct *b[], void **vals, int num_of_args, char *printf_string)
{
    int i, ret;
    av_alist alist;

    av_start_int (alist, &read_row, &ret);
    av_ptr (alist, struct some_struct *, a);
    av_ptr (alist, struct another_struct **, b);

    for (i=0;i<num_of_args;i++)
    {
        switch (type)  //for simplicity
        {
          case INT: {
              vals[i] = Malloc (sizeof (int));
              av_ptr (alist, int*, vals[i]);
              strcat (printf_string, "%d, ");
              break;
          }
          case FLOAT: {
               //Same thing
          }
          //etc
        }
    }

    av_call (alist);
    return (ret);
}
int av_read_行(struct some_struct*a,struct other_struct*b[],void**vals,int num_参数,char*printf字符串)
{
int i,ret;
AVU主义者;
av_开始_int(列表、读取行和返回);
av_ptr(列表,结构部分*,a);
av_ptr(列表,结构另一个结构**,b);

对于(i=0;i,我没有深入了解代码的更详细信息,但可以说:

  • 使用stack传递大量参数是不可取的,因为stack是有限的。我不确定avu stuff是否真的检查了stack限制
  • 难道没有更简单的方法来执行相同的操作,而不是将变量推送到堆栈中吗

  • 关于
    avcall
    我能轻松找到的唯一信息是2001年的,但它确实建议使用POSIX。如果你能在Linux上运行你的东西,会很快发现你的内存故障。这是一个很棒的工具。

    我认为你的strcat缺少了一些东西……我对av_u的东西不是很熟悉,但如果printfu字符串被覆盖,你会发现这是你正在使用的软件包吗?
    int av_read_row (struct some_struct *a, struct another_struct *b[], void **vals, int num_of_args, char *printf_string)
    {
        int i, ret;
        av_alist alist;
    
        av_start_int (alist, &read_row, &ret);
        av_ptr (alist, struct some_struct *, a);
        av_ptr (alist, struct another_struct **, b);
    
        for (i=0;i<num_of_args;i++)
        {
            switch (type)  //for simplicity
            {
              case INT: {
                  vals[i] = Malloc (sizeof (int));
                  av_ptr (alist, int*, vals[i]);
                  strcat (printf_string, "%d, ");
                  break;
              }
              case FLOAT: {
                   //Same thing
              }
              //etc
            }
        }
    
        av_call (alist);
        return (ret);
    }