1
\$\begingroup\$

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?

asked Jun 16, 2020 at 11:49
\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

The code you have written is fine, apart from three small issues:

  1. You need to check that format isn't null before calling vswprintf otherwise it crashes.
  2. 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.
  3. 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
\$\endgroup\$
2
  • \$\begingroup\$ Thanks for the review, I like your suggestions, I wonder if there is any measurable performance difference in using std::wstring vs new wchar_t \$\endgroup\$ Commented 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\$ Commented Jun 18, 2020 at 7:10

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.