Vsnprintf and varargs not working, strange results
I use vsnprintf
(as far as I know correctly) but get weird results. I have simplified the code to the following example:
void func(char *aaa, ...)
{
char *buf;
va_list args;
int size;
va_start(args, aaa);
size = vsnprintf(NULL, 0, aaa, args)+1;
buf = malloc(size);
vsnprintf(buf, size, aaa, args);
printf("%s",buf);
free(buf);
va_end(args);
}
int main(int argc, char **argv)
{
func("abc %s", "def\n");
return 0;
}
I would expect "abc def" to be printed, but instead I get "abc" followed by some garbage text. Does anyone have any idea where I went wrong?
source to share
va_start(args, aaa);
size = vsnprintf(NULL, 0, aaa, args)+1; // Reads all arguments
buf = malloc(size);
vsnprintf(buf, size, aaa, args); // Tries to read all arguments again
printf("%s",buf);
free(buf);
va_end(args);
See the commented lines. You have to reset args
between these two calls consuming all arguments.
Insert:
va_end(args); va_start(args, aaa);
source to share
When you pass a handle args
to vsnprintf (), it will change it internally in your case. If it is used again, it will not give correct arguments.
Use va_copy () to create a copy args
if you want to get optional arguments twice.
void func(char *aaa, ...)
{
char *buf;
va_list args , argsc ; //argsc is used in the second vsnprintf()
int size;
va_start(args, aaa);
va_copy( argsc , args ) ; //make a copy of args
size = vsnprintf(NULL, 0, aaa, args)+1;
buf = malloc(size);
vsnprintf(buf, size, aaa, argsc); //use the copy since args is not valid
printf("%s",buf);
free(buf);
va_end(args);
va_end(argsc); //destroy both
}
source to share