我在编写一些基于cstring的代码时遇到了这个Visual Studio警告,我似乎无法正确地摆脱它(即,不使用#pragma
)。
This answer在过去基本上为我解决了这个警告。然而,在这里的行为似乎更加怪异。
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'
填充字符串会在循环后的行中给出同样的警告。
如果我删除循环,即使它什么也不做,警告也会消失。
如果我在malloc
调用之前为len
变量添加一个0检查,那么警告也会消失。但是,请注意,这没有任何意义。我应该检查的值是(size_t)-1
,向其添加1会导致传递给malloc
的参数为0。这是我在VS中遇到这种奇怪的警告之前从未听说过的。
是我的问题,还是Visual Studio的警告系统在这里发疯了?因为我觉得我错过了一些非常明显的东西,但我看不到这段代码有任何可能出错的地方。
作为参考,len
变量最初是wcslen
调用的结果,它永远不会返回(size_t)-1
,因为这样的字符串将是可寻址存储器长度的两倍。
我写这种cstring操作代码已经快十年了,从来没有遇到过任何问题。这个警告让我怀疑我一直在做错什么。
编辑:void
函数错误地返回了原始代码,因为它是一个更大的函数的一个片段。下面是一个正确返回无值的截图。
1条答案
按热度按时间t1rydlwq1#
警告消息如下所示:
它显示:“str”是一个0字节数组。循环
for (size_t i = 0; i < len; i++)
可能不成立。我认为代码应该更改为:
警告将消失。
malloc的参数设置为len+1,只是为了防止出现越界错误。
如果size为0,malloc会在堆积中配置长度为零的项目,并传回指向该项目的有效指标。
如果参数是Len+1,malloc会在堆积中配置长度至少为1的项目,并传回指向该项目的有效指标。
如果你想知道
size_t len
的范围,你可以看到this link。一般来说,当你测量某个东西的大小时,应该使用size_t。很奇怪,size_t只需要表示0到SIZE_MAX字节之间,SIZE_MAX只需要65,535...
所以len+1!=0