【问题标题】:VS2019: [C6386] Buffer Overrun while toVS2019:[C6386] 缓冲区溢出而到
【发布时间】:2021-03-05 19:32:10
【问题描述】:
void Counting_Sort(vector<int>& A)
{
const int size = A.size();

int max = A[0];
for (int i = 1; i < size; i++)
    if (max > A[i])
        max = A[i];

int* C = new int[max + 1]{ 0 };
for (int i = 0; i < max + 1; i++)
    C[A[i]] = C[A[i]] + 1;

for (int i = 1; i < max + 1; i++)
    C[i] = C[i] + C[i - 1];

int* B = new int[size];
for (int i = size-1; i >= 0; i--)
    B[C[A[i]] - 1] = A[i];   // <-- Warning here

}

我不确定为什么会收到警告或它的确切含义。将 for 循环中的 size-1 设置为 size-2 会删除警告,但我不明白为什么。

【问题讨论】:

  • 与您当前的问题无关,但您有 2 个内存泄漏,应将 CB 替换为 std::vector&lt;int&gt;
  • 完整消息:&lt;source&gt;(23) : warning C6386: Buffer overrun while writing to 'B': the writable size is 'size*4' bytes, but '8' bytes might be written.: Lines: 7, 9, 10, 14, 15, 16, 15, 16, 15, 18, 19, 18, 21, 22, 23 live godbolt.org/z/z3h647 请记住,C6xxx 警告来自静态分析器,可能会产生误报
  • 您将A 中的值用作C 的索引,并将C 中的值用作B 的索引,但您没有显示A 的值实际上看起来像开始。请提供 minimal reproducible example 显示您正在使用的输入。
  • A[i] 的值是否有可能超出C[] 数组的范围?在用作C[] 数组的索引之前,您应该验证A[i] 是否在范围内。 B 数组也是如此。在使用它们之前验证您的索引。

标签: c++ visual-c++ buffer buffer-overrun


【解决方案1】:

我注意到您的示例代码存在四个不同的问题:

  1. 最大值计算不正确。你的情况应该是测试if (A[i] &gt; max)
  2. 计数排序算法的“累积步骤”应该对输入数据进行迭代。也就是说,循环应该如下(最多size,而不是max + 1):
for (int i = 0; i < size; i++)
    C[A[i]] = C[A[i]] + 1;
  1. 算法的最终循环忘记更新每个“计数排序箱”的目的地。也就是说,最终的循环应该如下:
for (int i = size - 1; i >= 0; i--) {
    B[C[A[i]] - 1] = A[i];
    C[A[i]] = C[A[i]] - 1;
}
  1. 完成后不要忘记在BC 上使用delete[]

这是完全编辑的结果:

#include <iostream>
#include <vector>

void Counting_Sort(std::vector<int>& A) {
    const int size = A.size();

    int max = A[0];
    for (int i = 1; i < size; i++)
        if (A[i] > max)
            max = A[i];

    int* C = new int[max + 1]{ 0 };
    for (int i = 0; i < size; i++)
        C[A[i]] = C[A[i]] + 1;

    for (int i = 1; i < max + 1; i++)
        C[i] = C[i] + C[i - 1];

    int* B = new int[size];
    for (int i = size-1; i >= 0; i--) {
        B[C[A[i]] - 1] = A[i];
        C[A[i]] = C[A[i]] - 1;
    }

    for (int i = 0; i < size; i++)
        std::cout << "B[" << i << "] is " << B[i] << "\n";

    delete[] B;
    delete[] C;
}

int main() {
    std::vector<int> A = {6, 1, 3, 3, 6, 9};
    Counting_Sort(A);
    return 0;
}

【讨论】:

  • 我看到 max+1 而不是 size 导致了警告,感谢指出其他问题。
【解决方案2】:

编译器说 B 的大小是 4xsize 字节长,但在某些情况下,可能会写入 8 个字节,这可能会超过 4xsize 字节的长度。

以 A = {10} 为例。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    • 1970-01-01
    • 2017-06-16
    • 2019-11-20
    • 1970-01-01
    • 2015-12-16
    • 1970-01-01
    相关资源
    最近更新 更多