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?

+3


source to share


2 answers


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

      

+3


source


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
}

      

+2


source







All Articles