【问题标题】:Using dynamically-allocated arrays causes C6386 Buffer Overrun warning from Code Analysis使用动态分配的数组会导致代码分析中的 C6386 缓冲区溢出警告
【发布时间】: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


    【解决方案1】:

    有趣的是,我可以通过为数组大小引入一个无意义的中间变量来消除警告,如下所示:

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

    我不知道为什么代码分析器喜欢这个,但不喜欢原始代码。

    如果我使用智能指针来保存动态分配,Analyzer 也很高兴,这会更简洁一些,可能一开始就应该这样写。

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

    【讨论】:

    • 我没有亲身经历,但像你这样的一些帖子让我怀疑 VS 代码分析的可靠性。
    猜你喜欢
    • 2017-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-11
    • 2023-03-11
    • 2021-03-03
    • 1970-01-01
    相关资源
    最近更新 更多