使用动态分配的数组会导致代码分析发出虚假的C6386缓冲区溢出警告
Using dynamically-allocated arrays causes spurious C6386 Buffer Overrun warning from Code Analysis
(注意:此问题与代码分析中错误的虚假C6386警告有关。它不是询问该警告的真实实例的问题的重复(
当我在C++中使用动态分配的数组时,我会收到Visual Studio 2019代码分析发出的虚假C6386警告。
这里有一个最小的可复制示例:
#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;
}
这里的意图是,我们有一个int向量,出于某种原因,我们希望将它们复制到一个动态分配的int数组中。(这个例子有点傻,但它说明了问题(。
请注意,在分配dynamicInts
数组AND期间,代码使用someInts
向量的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
阵列只是一个元素。
这似乎很奇怪。我知道"代码分析很难">但分析器肯定拥有它所需要的所有信息,就在那里推导数组长度和循环边界?
那么,这只是代码分析中的一个假阴性吗?还是我错过了什么?
如果它是一个假阴性,那么在不添加抑制并假设我们需要坚持使用动态分配的数组的情况下,避免此警告的最佳方法是什么?
有趣的是,我可以通过为数组的大小引入一个毫无意义的中间变量来消除警告,如下所示:
#include <vector>
int main()
{
std::vector<int> someInts{ 1, 2, 3 };
size_t numberOfInts = someInts.size();
int* dynamicInts = new int[numberOfInts];
for (size_t i = 0; i < numberOfInts; i++)
{
dynamicInts[i] = someInts[i];
}
delete[] dynamicInts;
}
我不知道为什么代码分析器喜欢这个,但不喜欢原始代码。
如果我使用智能指针来保存动态分配,Analyser也会很高兴,这有点整洁,可能是最初应该写的方式。
#include <vector>
#include <memory>
int main()
{
std::vector<int> someInts{ 1, 2, 3 };
std::unique_ptr<int[]> dynamicInts(new int[someInts.size()]);
for (size_t i = 0; i < someInts.size(); i++)
{
dynamicInts[i] = someInts[i];
}
}
相关文章:
- 警告处理为错误这里有什么问题
- C++字符*缓冲区的大小
- 为什么msgrcv()将垃圾字符馈送到缓冲区
- 使用动态分配的数组会导致代码分析发出虚假的C6386缓冲区溢出警告
- ostream过载时的缓冲区冲洗
- C++中的高效循环缓冲区,它将被传递给C样式数组函数参数
- cppcheck在const std::string[]上引发警告
- GCC对可能有效的代码抛出init list生存期警告
- 如何在BST的这个简单递归实现中消除警告
- Xaudio2在更改缓冲区或循环时弹出声音
- 关于std::move的使用,是否有编译警告
- g++ 在某个类成员未初始化时不发出警告
- 为什么我在leetcode上收到AddressSanitizer:地址0x602000000058上的堆缓冲区溢出错误
- 如何将图像传输到c++(dll)中的缓冲区,然后在c#的缓冲区中读/写
- 如何在cpp.中使用协议缓冲区存储大缓冲区/数组(char/int)
- OpenGL 调试上下文警告 -"将使用视频内存作为缓冲区异议的来源
- MSVC C6029 警告:缓冲区可能溢出,使用未经检查的值.检查缓冲区大小时,警告不会消失
- 为什么缓冲区超支警告(C4789)仅在编译器标志 /o2中发生
- 为什么在Visual Studio 2012上的代码分析中,此代码会发出缓冲区溢出警告(C6385/C6386)
- 是什么原因导致此缓冲区溢出警告超过64位VS2012编译环境