I was writing some cstring-based code while I ran into this Visual Studio warning that I cannot seem to get rid of properly (i.e. without using a #pragma
).
This answer basically solved this warning for me in the past. However, here the behaviour appears to be even more bizarre.
C6386: Buffer overrun while writing to 'str'.
The smallest piece of code required to replicate this error is as follows.
void test(const size_t len)
{
char* const str = malloc(len + 1);
if (str == NULL)
{
return;
}
for (size_t i = 0; i < len; i++) { }
str[len] = '\0';
}
The last line triggers this warning message.
Originally, I had code inside the loop which would write to the string, but apparently the code inside the loop has no effect on this warning. Filling the string with 'a'
gives the same exact warning on the line after the loop.
If I remove the loop, even though it does nothing at all, the warning disappears.
If I add a 0 check for the len
variable before the malloc
call, then the warning also disappears. However, please note that this make no sense. The value I should be checking for is (size_t)-1
, adding 1 to which would cause the argument passed to malloc
to be 0, which could trigger this undefined behaviour that I had never heard of before crossing paths with this curious warning in VS.
Is it me, or is it the Visual Studio warning system that is going crazy here? Because I feel like I am missing something completely obvious, yet I cannot see anything that could possibly go wrong with this code.
For reference, the len
variable was originally the result of a wcslen
call, which can never return (size_t)-1
simply because such string would be twice the length of the addressable memory.
I have been writing this kind of cstring manipulation code for nearly a decade now, and never once had I experienced any issues. This warning makes me wonder if I had been doing something wrong all this time.
Edit: The original code erroneously returned from a void
function because it was a snippet from an originally much larger function. Here is a screenshot with a proper valueless return.