2015-05-26 69 views
0

为什么使用vector :: reserve会改变sort的行为?std ::使用std :: vector :: reserve时,排序顺序是从最大到最小的?

std::vector<unsigned> xyz; 
xyz.reserve(3); 
xyz[0]=3; xyz[1]=1; xyz[2]=2; 
std::sort(xyz.begin(), xyz.end()); 
std::cout<<xyz[0]<<xyz[1]<<xyz[2]<<"\n"; 
//312 

xyz.clear(); 
xyz.push_back(3); xyz.push_back(1); xyz.push_back(2); 
std::sort(xyz.begin(), xyz.end()); 
std::cout<<xyz[0]<<xyz[1]<<xyz[2]<<"\n"; 
//123 
+2

储备仅保留存储器的项被存储,以便如果向量稍后需要时它将不必预留更多空间。它不会更改矢量认为它包含的项目的数量。你有一个零大小的数组,它有空间增长到3个项目而不分配更多的内存,但它仍然是一个零大小的数组。然后访问超出未定义行为的向量大小的项目。使用resize()来实际设置大小... – jcoder

回答

2

不,它与它无关。您的代码将进入未定义的行为。

储备不允许使用保留的空间直接像你这样在这里:

xyz.reserve(3); 
xyz[0]=3; xyz[1]=1; xyz[2]=2; 

它只是确保不会在元素的插入不重新分配。您没有插入它们,您使用了跳过界限检查的语法。因此,容器不知道元素在那里。

您可以使用at()这是operator[]的界限检查版本,它会炸毁。

的正确方法做到这一点是resize或正确地插入元件(有几种方法一样emplacepush等)

实施例:

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

int main() { 
    std::vector<unsigned> xyz; 
    xyz.reserve(3); // blows 
    // xyz.resize(3); // works 
    xyz.at(0)=3; xyz.at(1)=1; xyz.at(2)=2; 
    return 0; 
} 
2

我加在你的代码的一些评论:

xyz.reserve(3); // only revserve spaces for 3 elements, xyz.size() is still 0 
xyz[0]=3; xyz[1]=1; xyz[2]=2; // UB 
std::sort(xyz.begin(), xyz.end()); // There's nothing in xyz, so xyz.begin() == xyz.end(), so std::sort sort nothing here 
std::cout<<xyz[0]<<xyz[1]<<xyz[2]<<"\n"; // UB again 
2

这段代码

std::vector<unsigned> xyz; 
xyz.reserve(3); 
xyz[0]=3; xyz[1]=1; xyz[2]=2; 

是无效的。如果矢量的元素不存在,则不能使用下标运算符。成员函数保留不创建向量的元素。它只为未来的元素保留内存。在这种情况下,您必须使用push_back而不是下标运算符。或者,您可以使用会员功能resize而不是保留号。相反,保留它确实创建了矢量的指定数字元素。例如

std::vector<unsigned> xyz; 
xyz.resize(3); 
xyz[0]=3; xyz[1]=1; xyz[2]=2; 
相关问题