2015-05-26 68 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; 
相關問題