Tôi đang sử dụng thư viện ffcall (cụ thể là gói avcall của ffcall) để tự động đẩy các tham số đến các hàm variadic. tức là chúng tôi cóvoid con trỏ và ffcall thư viện
int blah (char *a, int b, double c, ...);
và chúng tôi muốn gọi hàm này với các giá trị được lấy từ người dùng. Để làm điều này, chúng ta tạo ra một phiên bản avcall của hàm:
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);
}
Bây giờ, chức năng Tôi đang sử dụng avcall với là:
int read_row (struct some_struct *a, struct another_struct *b[], ...);
Và nó được sử dụng như sau:
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);
}
Nhưng tôi muốn sử dụng avcall để nắm bắt một số tiền nhất định của các giá trị từ chức năng này và tôi không biết thông tin này trước. Vì vậy, tôi nghĩ rằng tôi chỉ muốn tạo ra một mảng các con trỏ void và sau đó không gian malloc theo loại:
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");
}
Và av_read_row
chỉ là:
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);
}
Tôi đã được trải qua một loạt các bộ nhớ tham nhũng lỗi và có vẻ như nó không giống như những gì tôi đang làm ở đây. Tôi không thể phát hiện ra bất cứ điều gì sai trái với cách tôi đã làm điều này, bạn có thể? Tại thời điểm này, nó không thích nó khi tôi cố gắng giải phóng mallocs bên trong vòng lặp trong khi av_read_row
. Bất cứ ai có thể nhìn thấy những gì tôi đang làm sai, nếu có gì?
Cảm ơn
Tôi nghĩ rằng strcat của bạn thiếu một cái gì đó ... Tôi không thực sự quen thuộc với các công cụ av_, nhưng nếu printf_string là ghi đè bạn sẽ nhận được một số kết quả khó chịu. –
Đây có phải là (http://www.haible.de/bruno/packages-ffcall.html) gói bạn đang sử dụng không? –