我们知道,当使用连续的内存块时,我们可以轻松地获得一个迭代器(此处为&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有什么解决方法吗?
答案 0 :(得分:8)
指针确实符合RandomAccessIterator
所要求的std::sort
标准。只要它们指向同一(连续)数组,它们是否指向堆栈内存或堆内存都没有关系。所以您可以简单地使用:
std::sort(arr, arr + len);
这就是说,std::vector
可能是在堆上分配数组的更好选择。它将使您免于自己管理内存的麻烦。
答案 1 :(得分:3)
是的,您可以在两种情况下以相同的方式使用std::sort
,std::sort
不知道或不在乎内存的分配方式。
答案 2 :(得分:2)
在C ++库中,迭代器基本上是花式指针。因此,将指针增加到数组的末尾以获取“ 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的编译器)认识到这种代码本质上是不安全的,因为您需要手动提供数组的长度。结果,如果尝试这样做,它们将导致(如果需要,可使用Compiler标志抑制)编译时错误,并建议您改用编译器提供的实用程序:
#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
答案 3 :(得分:1)
我可以在堆分配的原始数组上使用std :: sort吗?
是的
我不知道是否可以为此数组获得迭代器
可以。
指向元素的指针是数组的随机访问迭代器。对于自动数组,数组名称隐式衰减为一个指针,您可以将其用作数组开头的迭代器。对于动态数组,new[]
的结果已经是指针,即指向数组开头的迭代器。就像您的示例一样,您可以使用指针算术将指针指向末尾。
关于使用std::sort
,数组变量和指向动态数组的指针之间唯一的显着区别是,不能像使用指针一样将std::end
或std::size
与指针一起使用与数组变量。相反,您需要单独知道数组的大小。在这种情况下,您已将长度存储在变量len
中。