I'm trying to write a few wrappers for the standard sprintf
function from cstdio
. However, I'm having some weird behaviour and access violation crashes when running my program. I've simplified the problem and reproduced it on the code below:
#include <string>
#include <cstdio>
#include <cstdarg>
std::string vfmt(const std::string& format, va_list args)
{
int size = format.size() * 2;
char* buffer = new char[size];
while (vsprintf(buffer, format.c_str(), args) < 0)
{
delete[] buffer;
size *= 2;
buffer = new char[size];
}
return std::string(buffer);
}
std::string fmt(const std::string& format, ...)
{
va_list args;
va_start(args, format);
std::string res = vfmt(format, args);
va_end(args);
return res;
}
int main()
{
std::string s = fmt("Hello %s!", "world");
printf(s.c_str());
return 0;
}
This code produces a memory access violation when calling vsprintf
in vfmt
. However, when I change fmt
's function signature from fmt(const std::string& format, ...)
to fmt(const char* format, ...)
, I no longer crash, and everything works as expected. Why exactly is this happening?
Why is it that changing the type of the format
parameter from const std::string&
to const char*
solves the issue? Or does it only appear to be solved?