Visual Studio 2015 代码分析 C6386 警告缓冲区溢出

新手上路,请多包涵

我已经阅读了很多关于 Visual Studio 代码分析警告 C6386 的内容,但无法用我的代码找出这个特定问题。我已将其简化为以下小程序:

 unsigned int nNumItems = 0;

int main()
{
    int *nWords=nullptr;
    unsigned int nTotal;

    nTotal = 3 + 2 * nNumItems;
    nWords = new int[nTotal];

    nWords[0] = 1;
    nWords[1] = 2; // this is line 18, warning C6386

    delete[] nWords;
    return 0;
}

分析->运行代码分析->解决方案将给出以下警告:

file.cpp(18):警告 C6386:写入“nWords”时缓冲区溢出:可写大小为“nTotal*4”字节,但可能写入“8”字节。

这是合法的吗?现在,如果我移动我的全局变量并使其成为本地变量,警告就会消失!

 int main()
{
    unsigned int nNumItems = 0;
...
}

但我不能像在完整代码中那样做,这是一个成员变量。

同样,如果我将 nTotal 的定义移动到“ new int ”中,我也可以删除警告:

     nWords = new int[3 + 2 * nNumItems];

但我不能这样做,因为 nWords 在完整代码的其他地方被引用。

这只是 Visual Studio 静态代码分析器的问题,还是此代码的合法问题?

原文由 Tom M 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.3k
1 个回答

静态代码分析很难,跟踪像 3 + 2 * nNumItems 这样的表达式的可能值很难,跟踪 实际可能值 通常几乎是不可能的。这就是为什么它是一个 警告,而不是错误。到目前为止,显而易见。

现在,看看你如何描述这个警告的行为,我会打赌一个“错误”,或者更确切地说,我应该在静态分析器中以较少的压力和缺陷说出来。

我可以在原始 nWords[1] = 2 和全局 nNumItems 上看到此警告背后的一些想象中的可能原因。它们真的很奇怪,我认为合理的分析师不会将这样的规则添加到分析器中。另外,我是对的,那么您也应该在 nWords[0] = 1 上看到这些警告。

你没有看到它们的事实证明我的想法是错误的,所以我停在这里。

相反,我想专注于 静态代码分析很难。分析器及其规则编写得多么好并不重要。在某些情况下,它会出错,而在其他情况下,它会简单地失败,甚至无法猜测,而在其他情况下,它会超时并放手。直到我们在 AI 方面取得突破或在解决 NP 难题方面取得突破之前,您可能不得不习惯这样一个事实,即当您使用静态代码分析器时,您必须以他们可以理解的方式编写代码,不要指望他们能理解你能写的一切。

最后一个想法,当我看到这个错误时:

file.cpp(18):警告 C6386:写入“nWords”时缓冲区溢出:可写大小为“nTotal*4”字节,但可能写入“8”字节。

我注意到的第一件事是 nTotal*48 。如果您使用的是硬编码值,您可能会收到类似的错误

file.cpp(18):警告 C6386:写入“nWords”时缓冲区溢出:可写大小为“1024”字节,但可能会写入“8192”字节。

您看到 nTotal*4 的事实似乎意味着静态代码分析器实际上无法猜测 nTotal 下的值,并将其保留为符号名称,形成了一个无法与 8 。因此,分析器做了它唯一能做的事情——它报告了一个问题,并尽可能地描述了它。不过,这只是我的猜测。

// 编辑 - 丹关于猜测的答案的注释:nNumItems <- SIZE_MAX

我实际上认为他可能与 SIZE_MAX 差不多。我玩了一些微软的 SAT 求解器,他们做得很好的一件事是求解整数域中的一组约束。实际上 unsigned int x = SIZE_MAX; std::cout << ( (3+2*x)*sizeof(int) ); 打印 4(当然),这是 x 的唯一值,其表达式小于 8。

我很确定我玩过的 microsoft 的约束求解器可以在检查整数环域中 ((3+2*x)*4) < 8 的可满足性时检测到这种情况 - 因此可能会发出警告。但是,我希望警告包含结果并打印如下内容:

nTotal*4 < 8 当 {nTotal=1,nNumItems=4294967295}`

因为分析仪已经有了这些信息。但是,那是……可能对它期望太高了。它背后的开发人员可能不会考虑格式化如此详细的警告消息,或者认为当前的消息格式更加用户友好。

原文由 quetzalcoatl 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题