PredaWnia
PredaWnia

Reputation: 23

Problem using variable argument list and string formating

I have the following function that accepts a string and a list of arguments, the idea is that it works as a printf for the user. The function below is a minimal executable example of the function.

string description = "";

void error(string format, ...){
    va_list arguments;
    va_start(arguments, format);
    va_list arg_copy;
    va_copy(arg_copy, arguments);

    const int32_t size = snprintf(nullptr, 0, format.c_str(), arguments) + 1;
    const unique_ptr<char[]> buffer = make_unique<char[]>(size);
    va_end(arguments);

    snprintf(buffer.get(), size, format.c_str(), arg_copy);
    va_end(arg_copy);

    description += string(buffer.get(), buffer.get() + size - 1);
}

And I call it as follows.

int main()
{
    int a = 123;
    error("Format %d", a);
    cout<< description;

    return 0;
}

The expected output is: Format 123

The output result is (the number changes each execution): Format 378812424

I guess it is some problem with the memory but I am not able to discover where the problem is.

Upvotes: 0

Views: 354

Answers (1)

Remy Lebeau
Remy Lebeau

Reputation: 598134

You are using the wrong print function. By using snprintf(), you are printing the address of the va_list itself, not the values that it refers to.

To print a va_list, you need to use vsnprintf() instead, eg:

string description = "";

void error(string format, ...){
    va_list arguments;
    va_start(arguments, format);

    va_list arg_copy;
    va_copy(arg_copy, arguments);
    const int32_t size = vsnprintf(nullptr, 0, format.c_str(), arg_copy) + 1;
    va_end(arg_copy);

    vector<char> buffer(size);

    vsnprintf(buffer.data(), size, format.c_str(), arguments);
    va_end(arguments);

    description.append(buffer.data(), size - 1);
}

Upvotes: 2

Related Questions