I would like to design a function which takes a variable number of arguments, one of these arguments being itself a va_list; but something gets wrong in my code and I do not understand what...
WARNING — My question is not about designing a code doing what I wish to do (I have found a way to bypass the problem), but only about understanding what I did wrong...
To explain my question, let us start with a simple example: namely, a function ffprintf which acts like fprintf, but writing its contents onto several strings, strings whose number is indicated by the first argument of ffprintf, and whose identities are given by the very next arguments (the number of these arguments may vary from one call to another, so you have to use a variable argument list). Such a function would be used like this:
FILE *stream0, *stream1, *stream2;
int a, b;
ffprintf (3, stream0, stream1, stream2, "%d divided by %d worths %f", a, b, (double)a / b);
And its code would be:
void ffprintf (int z, ...)
 {va_list vlist, auxvlist;
  FILE **streams = malloc (z * sizeof(FILE *));
  va_start (vlist, z);
  for (int i = 0; i < z; ++i)
   {streams[i] = va_arg (vlist, FILE *); // Getting the next stream argument
   }
  char const *format = va_arg (vlist, char const *); // Getting the format argument
  for (int i = 0; i < z; ++i)
   {va_copy (auxvlist, vlist); // You have to work on a copy "auxvlist" of "vlist", for otherwise "vlist" would be altered by the next line
    vfprintf (streams[i], format, auxvlist);
    va_end (auxvlist);
   }
  va_end (vlist);
  free (streams);
 }
That works fine. Now, there is also the standard function vfprintf, whose prototype is vfprintf (FILE *stream, char const* format, va_list vlist);, and which you use like this to create another function having a variable argument list:
void fprintf_variant (FILE *stream, char const* format, ...)
 {
  va_list vlist;
  va_start (vlist, format);
  vfprintf (stream, format, vlist);
  va_end (vlist);
 }
That works fine too. Now, my goal is to combine both ideas to create a function which I would call vffprintf, which you would use like this:
FILE *stream0, *stream1, *stream2;
void fprintf_onto_streams012 (char const *format, ...)
 {va_list vlist;
  va_start (vlist, format);
  vffprintf (3, stream0, stream1, stream2, format, vlist);
  va_end (vlist);
 }
I have designed the following code:
void vffprintf (int z, ...)
 {va_list vlist, auxvlist, auxauxvlist;
  va_start (vlist, z);
  FILE **streams = malloc (z * sizeof(FILE *));
  for (int i = 0; i < z; ++i)
   {streams[i] = va_arg (vlist, FILE *);
   }
  char const *format = va_arg (vlist, char const *);
  va_copy (auxvlist, va_arg (vlist, va_list)); // Here I get the next argument of "vlist", knowing that this argument is of "va_list" type
  for (int i = 0; i < z; ++i)
   {va_copy (auxauxvlist, auxvlist);
    vfprintf (streams[i], format, auxvlist);
    va_end (auxauxvlist);
   }
  va_end (auxvlist);
  va_end (vlist);
  free (streams);
 }
This code compiles without a hitch, but it does not work properly... For instance, if I write the following complete code:
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
void vffprintf (int z, ...)
 {va_list vlist, auxvlist, auxauxvlist;
  FILE **streams = malloc (z * sizeof(FILE *));
  va_start (vlist, z);
  for (int i = 0; i < z; ++i)
   {streams[i] = va_arg (vlist, FILE *);
   }
  char const *format = va_arg (vlist, char const *);
  va_copy (auxvlist, va_arg (vlist, va_list));
  for (int i = 0; i < z; ++i)
   {va_copy (auxauxvlist, auxvlist);
    vfprintf (streams[i], format, auxauxvlist);
    va_end (auxauxvlist);
   }
  va_end (auxvlist);
  va_end (vlist);
  free (streams);
 }
void printf_variant (char const *format, ...)
 {va_list vlist;
  va_start (vlist, format);
  vffprintf (1, stdout, format, vlist);
  va_end (vlist);
 }
int main (void)
 {printf_variant ("Ramanujan's number is %d.\n", 1729);
  return 0;
 }
I get a segfault!... Why?!
P.-S.: Sorry for that very long question; but I wanted it to be perfectly clear, for it is rather technical...
P.-S.2: I used deliberately both tags "va-list" and "variableargumentlists" for this question, because which interests me is va_list, seen as a type, inside a (other) variable argument list, seen as a list... So these are really two different concepts here.
 
     
     
     
     
    