Visual Studio 2022 中 C6386 警告的不一致

Inconsistency of the C6386 warning in Visual Studio 2022

提问人:natiiix 提问时间:10/10/2022 最后编辑:Ted Lyngmonatiiix 更新时间:10/14/2022 访问量:379

问:

我正在编写一些基于 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';
}

最后一行触发此警告消息。

Warning message screenshot

最初,我在循环中有代码可以写入字符串,但显然循环中的代码对此警告没有影响。填充字符串会在循环后的行上给出相同的警告。'a'

如果我删除循环,即使它什么都不做,警告也会消失。

Removing the NOOP loop removes the warning

如果我在调用之前为变量添加 0 检查,则警告也会消失。但是,请注意,这毫无意义。我应该检查的值是 ,将 1 添加到该值将导致传递的参数为 0,这可能会触发这种未定义的行为,这是我在 VS 中遇到这个奇怪的警告之前从未听说过的。lenmalloc(size_t)-1malloc

Added len == 0 check

是我,还是 Visual Studio 警告系统在这里发疯了?因为我觉得我错过了一些完全明显的东西,但我看不到任何可能出错的东西。

作为参考,该变量最初是调用的结果,它永远不会返回,因为此类字符串的长度是可寻址内存长度的两倍。lenwcslen(size_t)-1

近十年来,我一直在编写这种字符串操作代码,但从未遇到过任何问题。这个警告让我怀疑我是否一直做错了什么。

编辑:原始代码错误地从函数返回,因为它是来自最初更大的函数的片段。这是一张带有适当无价值回报的屏幕截图。void

The value return from void function warning is irrelevant

C Visual-Studio 警告 IntelliSense

评论

0赞 Samuel Liew 10/10/2022
评论不用于扩展讨论;此对话已移至 Chat

答:

1赞 Jingmiao Xu-MSFT 10/10/2022 #1

警告消息如下所示:

enter image description here

它显示:“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';
}

警告消失了。enter image description here

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

评论

0赞 natiiix 10/10/2022
感谢您的输入,但是如果我像这样更改循环,我将不得不放置额外的逻辑来处理与字符串其余部分不同的最后一个字符(通过将终止字符写入其中)。唯一可能是 0 字节数组的方法是 if 溢出到 0,但这实际上不会发生。整个警告是否基于这种可能的溢出?另外,怎么可能?它甚至不是一个指针。所以基本上,它希望我添加一张支票?您是如何在错误列表中收到此警告的?我只能在编辑器中看到它。strlen + 1lenNULLlen + 1 != 0
0赞 Jingmiao Xu-MSFT 10/10/2022
“错误列表”窗口的上部有一个警告按钮,可以显示和隐藏警告信息。它看起来像是代码的问题,但不是智能感知。
0赞 natiiix 10/11/2022
我启用了所有三个级别,但无论如何,我都没有在列表中看到任何 IntelliSense 警告。有趣。。。“我的错误列表”配置看起来与屏幕截图中的配置完全相同。
0赞 Jingmiao Xu-MSFT 10/11/2022
是否在复选框中选择了“生成 + IntelliSense”?
0赞 natiiix 10/12/2022
是的,正如我所说,它看起来完全一样。