提问人:natiiix 提问时间:10/10/2022 最后编辑:Ted Lyngmonatiiix 更新时间:10/14/2022 访问量:379
Visual Studio 2022 中 C6386 警告的不一致
Inconsistency of the C6386 warning in Visual Studio 2022
问:
我正在编写一些基于 cstring 的代码,同时遇到了这个 Visual Studio 警告,我似乎无法正确摆脱(即不使用 ).#pragma
这个答案基本上为我解决了过去的这个警告。然而,这里的行为似乎更加奇怪。
C6386: Buffer overrun while writing to 'str'.
复制此错误所需的最小代码段如下所示。
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';
}
最后一行触发此警告消息。
最初,我在循环中有代码可以写入字符串,但显然循环中的代码对此警告没有影响。填充字符串会在循环后的行上给出相同的警告。'a'
如果我删除循环,即使它什么都不做,警告也会消失。
如果我在调用之前为变量添加 0 检查,则警告也会消失。但是,请注意,这毫无意义。我应该检查的值是 ,将 1 添加到该值将导致传递的参数为 0,这可能会触发这种未定义的行为,这是我在 VS 中遇到这个奇怪的警告之前从未听说过的。len
malloc
(size_t)-1
malloc
是我,还是 Visual Studio 警告系统在这里发疯了?因为我觉得我错过了一些完全明显的东西,但我看不到任何可能出错的东西。
作为参考,该变量最初是调用的结果,它永远不会返回,因为此类字符串的长度是可寻址内存长度的两倍。len
wcslen
(size_t)-1
近十年来,我一直在编写这种字符串操作代码,但从未遇到过任何问题。这个警告让我怀疑我是否一直做错了什么。
编辑:原始代码错误地从函数返回,因为它是来自最初更大的函数的片段。这是一张带有适当无价值回报的屏幕截图。void
答:
警告消息如下所示:
它显示:“str”是一个 0 字节数组。循环可能不成立。for (size_t i = 0; i < len; i++)
我认为代码应该改成这样:
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';
}
malloc 的参数设置为 len+1 只是为了防止越界错误。
如果 size 为 0,则 malloc 在堆中分配一个长度为零的项,并返回指向该项的有效指针。
如果参数为 Len+1,则 malloc 在堆中分配长度至少为 1 的项,并返回指向该项的有效指针。
如果你想知道的范围,你可以看到这个链接。size_t len
一般来说,每当您测量某物的大小时,都应该使用size_t。真的很奇怪,size_t只需要表示 0 到 SIZE_MAX 字节,而 SIZE_MAX 只需要 65,535 个字节......
所以len+1!=0
评论
str
len + 1
len
NULL
len + 1 != 0
评论