\$\begingroup\$
\$\endgroup\$
I am using c++17
and wide characters.
I have created a function to create a wchar_t* using a variable number of parameters ...
#include <stdarg.h> // the caller will free the memory wchar_t* GetMessage( const wchar_t* format, ... ) { va_list args; va_start(args, format); // get the size of the final string const auto size = vswprintf(nullptr, 0, format, args); // create the buffer const auto buffSize = size + 1; const auto buffer = new wchar_t[buffSize]; memset(buffer, 0, buffSize * sizeof(wchar_t) ); // create the string vswprintf_s(buffer, buffSize, format, args); va_end(args); // all done return buffer; }
Can you suggest a more efficient, standard, way of achieving the above?
1 Answer 1
\$\begingroup\$
\$\endgroup\$
2
The code you have written is fine, apart from three small issues:
- You need to check that format isn't null before calling vswprintf otherwise it crashes.
- There seems to be the potential for memory leaking, you are assuming the caller will always release the memory. It would return a std::wstring instead, no need to new the buffer and it is "automatically" released.
- Check the results of vswprintf_s() it will almost never fail, but when it does you'll be trying to track down what went wrong for days. :)
This is my version:
// the caller will free the memory
std::wstring getMessage(const wchar_t* format, ...)
{
std::wstring output; // function return value.
if (format != nullptr)
{
va_list args;
va_start(args, format);
const auto size = vswprintf(nullptr, 0, format, args); // get the size of the final string
if (size > 0) // If the above call worked
{
const auto buffSize = 1 + size;
output.reserve(buffSize); // create the buffer
if (vswprintf_s(output.data, buffSize, format, args) < 0)// create the string
{
output.clear(); // Empty the string if there is a problem
}
}
va_end(args);
}
return output;
}
answered Jun 16, 2020 at 20:17
-
\$\begingroup\$ Thanks for the review, I like your suggestions, I wonder if there is any measurable performance difference in using
std::wstring
vsnew wchar_t
\$\endgroup\$FFMG– FFMG2020年06月17日 15:12:18 +00:00Commented Jun 17, 2020 at 15:12 -
\$\begingroup\$ I would guess it would be worse, but safer. By coding wchar_t safely it would probably be slower. It depends on which is more important. \$\endgroup\$Code Gorilla– Code Gorilla2020年06月18日 07:10:18 +00:00Commented Jun 18, 2020 at 7:10
default