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
).
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.
CodePudding user response:
The warning message looks like this:
It shows: 'str' is a 0 byte array. The loop for (size_t i = 0; i < len; i )
may not hold.
I think the code should be changed to this:
void test(const size_t len)
{
char* const str = malloc(len 1);
if (str == NULL)
{
return;
}
for (size_t i = 0; i < len 1; i ) { }
str[len] = '\0';
}
The parameter of malloc is set to len 1 just to prevent out-of-bounds errors.
If size is 0, malloc allocates a zero-length item in the heap and returns a valid pointer to that item.
If the parameter is Len 1, malloc allocates an item of length at least 1 in the heap and returns a valid pointer to the item.
If you want to know the range of size_t len
you can see this link.
In general, size_t should be used whenever you are measuring the size of something. It is really strange that size_t is only required to represent between 0 and SIZE_MAX bytes and SIZE_MAX is only required to be 65,535...
So len 1!=0