2016-06-09 36 views
1

我寫了下面的代碼來測試一個矢量從另一個構造時的容量值。這是受到here問題的啓發。矢量的儲備()的怪異

#include <iostream> 
#include<vector> 
int main() 
{ 
    std::vector<int> a; 
    a.reserve(65536); 
    a[0]=10; 
    std::vector<int> b(a); //NOTE: b is constructed from a 
    std::cout<<a[0]<<" " <<b[0]; 
} 

程序成功地編譯,但是當它運行它扔以下錯誤

Error during execution: 
     Segmentation Fault(core dumped). 

然後檢查值初始化爲矢量,我改變了代碼如下所示:

#include <iostream> 
#include<vector> 
int main() 
{ 
    std::vector<int> a(65536); 
    a[0]=10; 
    std::vector<int> b(a); //NOTE: b is constructed from a 
    std::cout<<a[0]; 
} 

這一次的程序成功運行,沒有錯誤,給了輸出:

Output: 
     10 

然後我試圖把它改成下面的代碼:

#include <iostream> 
#include<vector> 
int main() 
{ 
    std::vector<int> a(65536); 
    a[0]=10; 
    std::vector<int> b(a); //NOTE: b is constructed from a 
    std::cout<<a[0]<<" " <<b[0]; 
} 

讓我吃驚下面的輸出來預期:

Output: 
    10 10 

我不明白爲什麼程序運行當矢量在構造函數中初始化爲大小時成功,但不是在使用reserve()給出容量時成功。

我也知道使用reserve()的向量的預留容量不會初始化向量的大小。下面的代碼也讓我更加困惑。

#include <iostream> 
#include<vector> 

int main() 
{ 
    std::vector<int> a; 
    a.reserve(1); 
    for(int i=0;i<5;i++) 
     a[i]=i; 
    std::vector<int> b(a); //NOTE: b is constructed from a 
    for(int i=0;i<5;i++) 
    std::cout<<a[i]<<" "; 
    std::cout<<"\n"<<a.size()<<" "<<a.capacity(); 
} 

在執行時它顯示以下怪異輸出:

Output: 
    0 1 2 3 4 
    0 1 

存儲的5個值的矢量,但矢量的大小保持爲0。

我無法理解此行爲向量。如何處理大小不變的值。

回答

2

你在混合容量和大小。容量只是一個實現功能。它允許您通過指定向量最終包含多少個元素來優化內存分配,因此每次向量增長時(實際增長策略也是實現細節),其實現不必重新分配內存。

大小是合乎邏輯的事情。它定義了實際存在的元素數量。它絕不能超過容量(如果載體的尺寸超出容量,事實上它的容量將會增加)。

訪問0 .. size - 1範圍以外的元素是非法的,根據您的運氣可能會或不會破壞,無論容量是多少。這就是所謂的未定義的行爲。

所以,當你調用方法或使用構造函數時,你必須弄清楚它是否設置容量或大小。

+0

你說得對,我實際上在開始時並不知道**運算符[] **在使用時沒有檢查邊界,所以我不知道它是未定義的行爲。 – kaartic

1

這是不允許的,你只是在有效內存之外寫的。

std::vector<int> a; 
a.reserve(65536); 
a[0]=10; 

你需要使用構造

std::vector<int> a(65536); 
a[0]=10; 

resize

std::vector<int> a; 
a.resize(65536); 
a[0]=10; 

push_back

std::vector<int> a; 
a.reserve(65536); 
a.push_back(10); 

reserve改變可用的capacity的載體,resize更改載體的實際sizeYou can read more about that here

+0

此外:在崩潰示例中(使用保留),a的大小仍然爲0,並且複製構造函數創建(合法!)一個空向量,顯然沒有分配存儲空間。在其中一個運行示例中檢查B的容量。它肯定會小於65536,因爲複製矢量意味着複製它的內容(元素從0到size()),但容量不是這個語義的一部分。 – Aconcagua

0

std::vectorreserve()將預先分配的元件,但它並不意味着元件被創建的,以及訪問a[0]而不產生一個元素也是合法的。

您可以使用resize()來創建元素。試試這個:

#include <iostream> 
#include<vector> 
int main() 
{ 
    std::vector<int> a; 
    a.resize(65536); 
    a[0]=10; 
    std::vector<int> b(a); //NOTE: b is constructed from a 
    std::cout<<a[0]<<" " <<b[0]; 
} 
+0

訪問元素是未定義的行爲,不是非法的。 – rubenvb