VS2019:[C6386][C6001] 关于修改计数排序的警告

问题描述

#include <iostream>
#include <string>
#include <vector>
using namespace std;

void MCounting_Sort(vector<int>& A)
{
const int size = A.size();

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

for (int i = 0; i < size; i++)
    A[i] = A[i] - min;

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;

int* B = new int[size];
int pos = 0;
for (int i = 0; i < max + 1; i++)
    if (C[i] > 0)
        for (int j = 0; j < C[i]; j++)
            B[pos++] = i;   // <-- C6386 Buffer overrun...
        
for (int i = 0; i < size; i++)
    A[i] = B[i] + min;   // <-- C6001 Using uninitialized memory "B"

delete[] B;
delete[] C;
}

int main()
{
vector<int> A {7,2,18,5};
for(unsigned int i=0; i<A.size(); i++) cout<<A[i]<<" ";
cout<<endl;
MCounting_Sort(A);
for(unsigned int i=0; i<A.size(); i++) cout<<A[i]<<" ";
}

输出

7 2 18 5 
2 5 7 18 

排序算法有效(也适用于负数),但是我收到了这两个警告,我不确定我是否可以解决它们,因为算法本身可能不好,但它是学校作业。也许我确实写错了什么。

解决方法

正如其他人在对您的问题的评论中所说的那样,如果您避免使用“原始”指针并使用 STL 提供的容器,您的代码会好得多。

然而,碰巧的是,MSVC 给出的两个警告可以通过对单行代码进行“微不足道”的修改来轻松解决。

您可以简单地在 B 数据的分配中添加一个初始化列表(就像您为 C 所做的那样)并确保您在其中分配至少 2 个整数那个数组。后者通常可以使用 std::max(size,2) 调用的 [] 中的 new 之类的表达式来实现;但是,由于您定义了一个名为 max 的局部变量,因此您不能使用该函数。

相反,您可以更改这一行:

int* B = new int[size];

为此:

int* B = new int[size < 2 ? 2 : size] { 0 }; // Ensure at least 2 elements and initialize

作为旁注,您可能喜欢阅读以下内容:Why is "using namespace std;" considered bad practice? 因为,如果您将 using namespace std; 行替换为单独的 using 语句,您实际使用的 STL 元素,那么您可以同时使用名为 max 的局部变量和std::max(size,2) 调用中使用 new 表达式。

以下三行将作为合适的替代:

using std::vector;
using std::cout;
using std::endl;

或者,如果您的编译器符合 C++17(或更高版本)标准,您可以将所有三个放在一个语句中:

using std::vector,std::cout,std::endl;