0
votes

I'm writing a small application to target Win32 using C++. The compiler is set to support unicode and I'm compiling in x64 mode. I'm using Visual Studio 2019.

Everytime I call swprintf_s, like below:

wchar_t buff[500] = { 0 };
swprintf_s(buff, sizeof(buff), L"Could not free DLL handle: 0x%X\n", GetLastError());
OutputDebugString(buff);

...I receive the following C6386 compiler warning:

C6386: Buffer overrun while writing to 'buff': the writable size is '1000' bytes, but '2000' bytes might be written.

As an experiment, if I doubled the size of the buffer...

wchar_t buff[1000] = { 0 };
swprintf_s(buff, sizeof(buff), L"Could not free DLL handle: 0x%X\n", GetLastError());
OutputDebugString(buff);

...the ranges within the warning simply shift up in accordance:

C6386: Buffer overrun while writing to 'buff': the writable size is '2000' bytes, but '4000' bytes might be written.

I'm wondering if someone might be able to help me understand why the above code (when explicitly passing the size of the buffer) generates a buffer overrun warning and, how I might go about fixing this.

1
sizeof returns the number of bytes, swprintf_s needs the number of chars. sizeof(wchar_t) != 1, you probably want sizeof(buff)/sizeof(wchar_t). - van dench
Thanks, I find the documentation confusing as it states: int swprintf_s(wchar_t *buffer, size_t sizeOfBuffer, const wchar_t *format, ...); (Second parameter named sizeOfBuffer) - Jon Matthews
@JonMatthews the documentation states: "sizeOfBuffer Maximum number of characters to store." - Remy Lebeau
Since this question is tagged c++, why aren't you using the C++-only function template instead? No need to specify the length in elements, meaning there's no opportunity to pass the wrong value. - IInspectable

1 Answers

1
votes

As commented by van dench, the second parameter is the number of chars, not the size of the buffer in bytes.

Correct code:

wchar_t buff[500] = { 0 };
swprintf_s(buff, 500, L"Could not free DLL handle: 0x%X\n", GetLastError());
OutputDebugString(buff);