首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Visual 2022中C6386警告的不一致性

Visual 2022中C6386警告的不一致性
EN

Stack Overflow用户
提问于 2022-10-09 16:34:11
回答 1查看 96关注 0票数 0

当我遇到这个Visual时,我正在编写一些基于cstring的代码,警告说我似乎无法正确地处理掉(即不使用#pragma)。

这个答案过去基本上为我解决了这个问题。然而,在这里,这种行为似乎更加怪异。

代码语言:javascript
复制
C6386: Buffer overrun while writing to 'str'.

复制此错误所需的最小代码如下所示。

代码语言:javascript
复制
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函数返回,因为它是一个原本大得多的函数的片段。这是一个截图,有一个适当的无价值回报。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-10-10 06:46:18

警告消息如下所示:

它显示:'str‘是一个0字节数组。循环for (size_t i = 0; i < len; i++)可能无法保持。

我认为应该将代码改为:

代码语言:javascript
复制
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

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74006547

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档