当我遇到这个Visual时,我正在编写一些基于cstring的代码,警告说我似乎无法正确地处理掉(即不使用#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'填充字符串时,在循环后的行上也会发出相同的警告。
如果我删除循环,即使它什么也不做,警告就会消失。

如果我在len调用之前为malloc变量添加0检查,那么警告也会消失。然而,请注意,这是没有意义的。我应该检查的值是(size_t)-1,添加了1,这将导致传递给malloc的参数为0,这可能触发我在交叉路径之前从未听说过的未定义行为,并在VS中发出这个奇怪的警告。

是我,还是Visual警告系统在这里疯狂了?因为我觉得我遗漏了一些完全显而易见的东西,但我看不到这段代码可能出错的任何东西。
作为参考,len变量最初是wcslen调用的结果,它永远不能返回(size_t)-1,因为这样的字符串将是可寻址内存的两倍长。
近十年来,我一直在编写这种cstring操作代码,从来没有遇到过任何问题。这一警告使我怀疑自己是否一直在做错事。
编辑:原始代码错误地从一个void函数返回,因为它是一个原本大得多的函数的片段。这是一个截图,有一个适当的无价值回报。

发布于 2022-10-10 06:46:18
警告消息如下所示:

它显示:'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';
}警告就会消失。

马洛的参数设置为len+1,只是为了防止越界错误.
如果大小为0,malloc将在堆中分配一个零长度项,并返回指向该项的有效指针。
如果参数为Len+1,malloc将在堆中分配长度至少为1的项,并返回指向该项的有效指针。
如果您想知道size_t len的范围,可以看到此链接。
通常,当您测量某物的大小时,应该使用size_t。非常奇怪的是,size_t只需要表示0到SIZE_MAX字节之间的值,而SIZE_MAX只需要65,535字节。
所以len+1!=0
https://stackoverflow.com/questions/74006547
复制相似问题