Visual Studio 2022中的C6386警告不一致

0pizxfdo  于 2022-11-17  发布在  其他
关注(0)|答案(1)|浏览(251)

我在编写一些基于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函数错误地返回了原始代码,因为它是一个更大的函数的一个片段。下面是一个正确返回无值的截图。

t1rydlwq

t1rydlwq1#

警告消息如下所示:

它显示:“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的范围,你可以看到this link
一般来说,当你测量某个东西的大小时,应该使用size_t。很奇怪,size_t只需要表示0到SIZE_MAX字节之间,SIZE_MAX只需要65,535...
所以len+1!=0

相关问题