2009-11-28 11 views
5

私はffcall(特にffcallのavcallパッケージ)ライブラリを使用して、変数を可変関数に動的にプッシュします。すなわち、我々はvoidポインタとffcallライブラリ

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); 
} 

は今、私はavcall使用しています機能は次のとおりです。

int read_row (struct some_struct *a, struct another_struct *b[], ...); 

そしてそれはそうと同じように使用されます。

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を使ってこの関数からある量の値を取得したいと思います。私はこの情報を事前に知っていません。

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_read_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); 
} 

私は、メモリの破損の束を経験してきたので、私はちょうど種類に応じて、ボイドポインタと、その後のmallocスペースの配列を作成しようと思いましたエラーと私はここで何をやっているのが好きではないように見えます。私はこれをやったやり方で何か間違った点を見つけることはできないのですか?現時点では、ループの中でav_read_rowの中のmallocsを解放しようとすると、それは好きではありません。誰かが私が間違っていることを見てもらえますか?

おかげ

+0

あなたのstrcatが何かを見逃していると思います... 私はav_ stuffにはあまり慣れていませんが、printf_stringが上書きされていれば厄介な結果になるでしょう。 –

+1

これは(http://www.haible.de/bruno/packages-ffcall.html)パッケージを使用していますか? –

答えて

0

私はコードのより細かい詳細には触れませんでしたが、引数の数が多いを通過させるためのスタックを使用して、次の

  1. を言うことができるスタックが限られているとして、お勧めできません。 av_stuffが実際にスタック制限をチェックするかどうかはわかりません。
  2. 変数をスタックするのではなく、同じ操作を行う簡単な方法はありませんか?
1

avcallについて簡単に知ることができる唯一の情報は2001年ですが、POSIXを示唆しています。あなたがLinux上であなたのものを走らせることができるなら、valgrindはあなたの記憶障害を見つけるでしょう。それはすばらしいツールです。

関連する問題