简体   繁体   English

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

[英]VS2019: [C6386][C6001] warnings on modified counting sort

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

output: output:

7 2 18 5 
2 5 7 18 

The sorting algorithm works (also for negative numbers), but I get these two warnings, I'm not sure if I can fix them, because the algorithm itself probably isn't good, but it's a school assignment.排序算法有效(也适用于负数),但我收到这两个警告,我不确定是否可以修复它们,因为算法本身可能不好,但它是学校作业。 Maybe I did write something wrong though.也许我确实写错了。

As others have said in the comments to your question, your code would be far better if you avoided using 'raw' pointers and made use of the containers provided by the STL.正如其他人在对您的问题的评论中所说的那样,如果您避免使用“原始”指针并使用 STL 提供的容器,您的代码会好得多。

However, as it happens, the two warnings that the MSVC gives can be readily addressed by a 'trivial' modification to a single line of your code.然而,碰巧的是,MSVC 给出的两个警告可以很容易地通过对单行代码的“微不足道”的修改来解决。

You can simply add an initializer list to your allocation of the B data (as you have done for C ) and ensure that you allocate at least 2 integers in that array.您可以简单地将初始化列表添加到B数据的分配中(就像您对C所做的那样)并确保在该数组中分配至少2 个整数。 The latter would normally be achieved using an expression like std::max(size, 2) inside the [] of the new call;后者通常可以在new调用的[]中使用类似std::max(size, 2)的表达式来实现; however, as you have defined a local variable called max , you cannot use that function.但是,由于您定义了一个名为max的局部变量,因此您不能使用该 function。

Instead, you can just change this line:相反,您可以更改此行:

int* B = new int[size];

to this:对此:

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

As a side note, you may like to read this: Why is "using namespace std;"作为旁注,您可能想阅读以下内容:为什么“使用命名空间标准;” considered bad practice?被认为是不好的做法? Because, if you replace your using namespace std;因为,如果你替换你的using namespace std; line with individual using statements for only those STL elements that you actually use, then you can have both a local variable called max and use the std::max(size, 2) expression in your new call.针对您实际使用的那些 STL 元素的单个using语句一致,那么您可以同时拥有一个名为max的局部变量new调用中使用std::max(size, 2)表达式。

The following three lines will serve as a suitable replacement:以下三行将作为合适的替代品:

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

Or, if your compiler conforms to the C++17 (or a later) Standard, you can put all three in one statement:或者,如果您的编译器符合 C++17(或更高版本)标准,您可以将所有三个放在一个语句中:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM