estoy usando el ffcall (específicamente el paquete de avcall ffcall) biblioteca para empujar de forma dinámica los parámetros a funciones variadic. es decir, tenemospunteros void y biblioteca ffcall
int blah (char *a, int b, double c, ...);
y queremos llamar a esta función con los valores tomados del usuario. Para ello, creamos una versión avcall de la función:
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);
}
Ahora, la función que estoy usando avcall con es:
int read_row (struct some_struct *a, struct another_struct *b[], ...);
y se utiliza de esta manera:
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);
}
Pero quiero usar avcall para capturar una cierta cantidad de valores de esta función y no sé esta información de antemano. Así que pensé que acababa de crear una matriz de punteros void y luego el espacio malloc según el tipo:
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");
}
Y av_read_row
es simplemente:
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);
}
que han estado experimentando un montón de corrupción de memoria errores y parece que no le gusta lo que estoy haciendo aquí. No veo nada malo con la forma en que hice esto, ¿o sí? Por el momento, no me gusta cuando intento liberar los mallocs dentro del ciclo while av_read_row
. ¿Alguien puede ver lo que estoy haciendo mal, en todo caso?
Gracias
Creo que a su strcat le falta algo ... No estoy muy familiarizado con las cosas av_, pero si printf_string se sobrescribe obtendrá algunos resultados desagradables. –
¿Es este (http://www.haible.de/bruno/packages-ffcall.html) el paquete que está utilizando? –