【发布时间】:2020-07-12 19:51:14
【问题描述】:
当我在 C++ 中使用动态分配的数组时,我会收到来自 Visual Studio 2019 代码分析的 C6386 warning。
这是一个最小的可重现示例:
#include <vector>
int main()
{
std::vector<int> someInts{ 1, 2, 3 };
int* dynamicInts = new int[someInts.size()];
for (size_t i = 0; i < someInts.size(); i++)
{
dynamicInts[i] = someInts[i];
}
delete[] dynamicInts;
}
这里的意图是我们有一个整数向量,并且出于某种原因我们想要将它们复制到一个动态分配的整数数组中。 (有点愚蠢的例子,但它说明了问题)。
它在分配dynamicInts 数组期间使用向量的size() 作为循环的上限,因此我可以看到缓冲区溢出应该没有问题。
但是这段代码会生成:
main.cpp(11): warning C6386: Buffer overrun while writing to 'dynamicInts': the writable size is 'someInts.public: unsigned int __thiscall std::vector<int,class std::allocator<int> >::size(void)const ()*4' bytes, but '8' bytes might be written.
错误列表中的详细解释解释如下:
7: 'dynamicInts' is an array of 1 elements (4 bytes)
9: Enter this loop. (assume 'i<someInts.size()')
9: 'i' may equal 1
9: Continue this loop. (assume 'i<someInts.size()')
11: 'i' is an In/Out argument to 'std::vector<int,std::allocator<int> >::[]'
11: Invalid to write to 'dynamicInts[1]'. (writable range is 0 to 0)
这些消息表明分析器认为dynamicsInts 数组只是一个元素。
这似乎很奇怪。我知道“代码分析很难”,但是分析器肯定有它需要的所有信息来推导数组长度和循环边界?
所以这只是代码分析的误报吗?还是我错过了什么?
如果它是假阴性,那么在不添加抑制和假设我们需要坚持使用动态分配的数组的情况下避免此警告的最佳方法是什么?
【问题讨论】:
标签: c++ visual-c++ visual-studio-2019 code-analysis static-code-analysis