Visual Studio 2015代码分析C6386警告缓冲区溢出 [英] Visual Studio 2015 Code Analysis C6386 warns of buffer overrun

查看:561
本文介绍了Visual Studio 2015代码分析C6386警告缓冲区溢出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经阅读了很多有关Visual Studio代码分析警告C8386的内容,但无法弄清楚我的代码是否存在这个特定问题。我将其简化为以下小程序:

I've read a lot about the Visual Studio Code Analysis warning C8386, but can't figure out this particular issue with my code. I've reduced it to the following small program:

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;
}

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

Analyze->Run Code Analysis->On Solution will give the following warning:


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

file.cpp(18): warning C6386: Buffer overrun while writing to 'nWords': the writable size is 'nTotal*4' bytes, but '8' bytes might be written.

这是合法的吗?现在,如果我移动全局变量并将其设置为局部变量,警告将消失!

Is this legit? Now, if I move my global variable and make it local, the warning disappears!

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

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

But I can't do this as in the full code, this is a member variable.

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

Likewise, if I move the definition of nTotal into the 'new int', I can also remove the warning:

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

但是我不能这样做,因为 nWords 在其他放在完整代码中。

But I can't do this as nWords is referred to in other places in the full code.

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

Is this just an issue with the Visual Studio static code analyzer, or is it a legitimate issue with this code?

推荐答案

静态代码分析很困难,要跟踪诸如 3 + 2 * nNumItems 这样的表达式的可能值很难,而且追踪实际可能的值通常几乎是不可能的。这就是为什么它是警告而不是错误的原因。到目前为止,对于显而易见的问题。

Static code analysis is hard, tracing possible values of an expression like 3 + 2 * nNumItems is hard, and tracing actual possible values is often near to impossible. This is why it is a warning, not error. So far for the obvious.

现在,看看您如何描述此警告的行为,我敢打赌一个 bug,或者我应该这样说:

Now, looking at how you describe that this warning behaves, I would bet on a "bug", or rather, I should say it with less stress, deficiency, in the static analyzer.

我可以在原始 nWords [1] = 2 <上看到此警告背后的一些假想可能原因/ code>和全局 nNumItems 。他们真的很奇怪,我认为没有一个合理的分析师会向分析仪添加此类规则。另外,我是对的,那么您也应该在 nWords [0] = 1 上出现这些警告。

I can see some imaginary possible causes behind this warning on original nWords[1] = 2 and global nNumItems. They are really weird and I don't think a reasonable analyst would add such rules to the analyzer. Also, I were right, then you should have these warnings on nWords[0] = 1 as well.

您看不到它们的事实证明了我的想法是错误的,所以我就在这里停止。

The fact that you don't see them on that proves my ideas wrong, so I stop here.

相反,我想重点关注该静态代码分析很难。分析器及其规则的编写方式是否良好都无关紧要。在某些情况下,它会出错,而在其他情况下,它只会失败并且甚至无法猜测,在其他情况下,它会超时并放手。在我们在AI方面取得一些突破或在解决NP难题方面取得突破之前,您可能必须习惯一个事实,即在使用静态代码分析器时,必须以一种可以理解的方式编写代码,

Instead, I would like to focus on that static code analysis is hard. It does not matter how well-written the analyzer and its rules are. For some cases, it will make errors, and for other cases it will simply fail and won't be even able to guess, and for other cases it will timeout and just let go. Until we have some breakthrough in AI or breakthrough in solving NP-hard problems, you will probably have to get used to the fact, that when you are using static code analyzers, then you have to write code in a way that they can comprehend, not count on that they can comprehend everything you can write.

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

Last thought, when I see this error:


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

file.cpp(18): warning C6386: Buffer overrun while writing to 'nWords': the writable size is 'nTotal*4' bytes, but '8' bytes might be written.

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

the first thing that I notice is nTotal*4 and 8. If you were using a hardcoded values, you would probably get an error like


file.cpp(18)的错误:警告C6386:缓冲区溢出写入'nWords':可写大小为'1024'字节,但可能写入'8192'字节。

file.cpp(18): warning C6386: Buffer overrun while writing to 'nWords': the writable size is '1024' bytes, but '8192' bytes might be written.

您会看到 nTotal * 4 似乎暗示静态代码分析器实际上无法猜测 nTotal 下的值,并且它离开了它作为符号名,形成了 8 无法比拟的表达式。因此,分析仪做了唯一能做的事情-它报告了一个问题,并尽可能地描述了它。

The fact that you see nTotal*4 seems to imply that the static code analyzer actually failed to guess the value under nTotal and it left it as symbolic name, which formed an expression incomparable to 8. Therefore, the analyzer did theonly thing it could - it reported a problem, and described it as well as it could. Still, it's just my guess.

//编辑-Dan对猜测的回答要注意:nNumItems<-SIZE_MAX

// EDIT - note for Dan's answer about guessing: nNumItems <- SIZE_MAX

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

I actually think that he's may be quite about the SIZE_MAX. I played a bit with some SAT solvers from Microsoft, and one thing they did well was solving set of constraints in integer domain. Actually unsigned int x = SIZE_MAX; std::cout << ( (3+2*x)*sizeof(int) ); prints 4 (of course), and that is the only value of x for which the expression is less than 8.

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

I'm pretty sure that the constraint solver from microsoft I played with can detect this case when checking satisfiability of ((3+2*x)*4) < 8 in integer ring domain - hence the warning could be issued. However, I would expect the warning to include the result and print something like:


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

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

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

since the analyzer had would have this information already. But then, that's.. probably expecting too much from it. Developers behind it probably wouldn't have thought of formatting such detailed warning message, or considered current format of the message to be more user-friendly.

这篇关于Visual Studio 2015代码分析C6386警告缓冲区溢出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆