我可以在堆分配的原始数组上使用 std::sort 吗?

Can I use std::sort on heap allocated raw arrays?

我们知道,当使用连续的内存块时,我们可以很容易地得到一个迭代器(这里是&arra[0]arra)并将迭代器传递给std::sort。

例如:

int arra[100];
    for (int i = 0; i < 100; i++) {
        arra[i] = rand() % 32000;
    }
    for (int i = 0; i < len; i++)std::cout << arra[i]<<" ";
    std::sort(arra,arra+100);

现在如果我有一个分配给堆的数组,比如 arr 这里:

int len;
    len = 100;
    int* arr = new int[len];
    for (int i = 0; i < len; i++) {
        arr[i] = rand() % 32000;
    }

我不知道我是否可以获得这个数组的迭代器,所以我可以对这个数组使用 std::sort 吗? 如果没有,是否有任何解决方法可以在这样的数组上使用 std::sort?

指针确实符合 RandomAccessIterator which is required by std::sort 的标准。它们指向栈内存还是堆内存并不重要,只要它们指向同一个(连续的)数组即可。所以你可以简单地使用:

std::sort(arr, arr + len);

也就是说,std::vector 可能是在堆上分配数组的更好选择。它会让您免去自己管理内存的麻烦。

是的,您可以在两种情况下以相同的方式使用 std::sortstd::sort 不知道也不关心内存是如何分配的。

Can I use std::sort on heap allocated raw arrays?

是的。

I don't know whether I can get an iterator for this array

可以。

指向元素的指针是数组的随机访问迭代器。在自动数组的情况下,数组名称隐式衰减为一个指针,您可以将其用作指向数组开头的迭代器。在动态数组的情况下,new[] 的结果已经是一个指针,即指向数组开头的迭代器。您可以像示例中一样使用指针运算获取指向末尾的指针。

关于 std::sort 的使用,数组变量和指向动态数组的指针之间的唯一显着区别是您不能将 std::endstd::size 与类似的指针一起使用你可以用一个数组变量。相反,您需要单独知道数组的大小。在这种情况下,您已将长度存储在变量 len.

在 C++ 库中,迭代器基本上就是花式指针。因此,standard-compliant 只是将指针递增到数组的末尾以获得 "end" 指针:

#include<algorithm>
#include<iostream>

int main() {
    int len;
    len = 100;
    int* arr = new int[len];
    for (int i = 0; i < len; i++) {
        arr[i] = rand() % 32000;
    }
    //Valid, Defined Behavior that works as expected
    std::sort(arr, arr + len);
    //alternative, to make the code easier to read:
    //auto begin = arr;
    //auto end = arr + len;
    //std::sort(begin, end);
    for(int i = 0; i < len; i++)
        std::cout << arr[i] << std::endl;
}

但是,一些编译器(如 Visual Studio 的编译器)认识到这种代码本质上是不安全的,因为您需要手动提供数组的长度。因此,如果您尝试这样做,它们将导致(如果需要,可以使用编译器标志来抑制)​​Compile-time 错误,建议您改用 compiler-provided 实用程序:

#include<algorithm>
#include<iostream>

int main() {
    int len;
    len = 100;
    int* arr = new int[len];
    for (int i = 0; i < len; i++) {
        arr[i] = rand() % 32000;
    }

    //MSVC Specific Code!
    auto begin = stdext::make_checked_array_iterator(arr, len);
    auto end = arr + len;
    std::sort(begin, end);
    for(int i = 0; i < len; i++)
        std::cout << arr[i] << std::endl;
}

有关 Visual Studio 编译器这一特殊快速的更多信息,请参见此处:https://docs.microsoft.com/en-us/cpp/standard-library/checked-iterators?view=vs-2019