2012-01-31 41 views
3

我試圖做這樣的事情:小心矢量::儲備?

#include <vector> 
#include <algorithm> 

int main() 
{ 
    int l[] = {1,2,3,4}; 
    vector<int> vi(4); 
    copy(l, l+4, vi.begin()); 

    do_stuff(); 
} 

上面的代碼可以編譯,沒有任何錯誤運行。然後,我把它改爲這個:

int main() 
{ 
    int l[] = {1,2,3,4}; 
    vector<int> vi; 
    vi.reserve(4); //different from the above code 
    copy(l, l+4, vi.begin()); 

    do_stuff(); 
} 

根據代碼,我改變vector<int> vi(4);vector<int> vi; vi.reserve(4);問題就來了,那就是改變的代碼可以編譯,但在運行時出現賽格故障。

根據gdb,seg-fault發生在函數do_stuff();中。

這是爲什麼?我做出的改變是否重要?我不能在這裏使用reserve嗎?

+0

你可能打算叫'vi.resize(4)',而不是'vi.reserve(4) '。但是,就像在你的第一段代碼中一樣,這將不必要地用四個'0'元素初始化矢量。最好'保留()'並使用'std :: back_inserter'或者立即用正確的數據初始化它。 – sbi 2012-01-31 20:11:16

回答

9

reserve()方法只分配內存,但保留它未初始化。它隻影響capacity(),但size()將保持不變。

如果要創建多個實例,則應使用分配內存的resize(),並創建與傳遞給resize()的參數一樣多的實例。

+0

但是在兩者中,'vi.size()'應該在'copy(...)'之後是'4',對吧? – Alcott 2012-01-31 09:22:29

+0

@Alcott:只複製副本,不會調整矢量大小()。它只有迭代器。就好像你寫了一個數組的邊界。 – PlasmaHH 2012-01-31 09:24:21

+3

@Alcott:如果你不相信Als的「尺寸不會改變」,那就測試一下。 'vector vi; vi.reserve(4); std :: cout << vi.size()<<'\ n';'。它打印'0'。 – 2012-01-31 09:26:04

1

從一個特定C++ reference

在任何情況下,在通話[向量::儲備]從不影響包含於載體的元素,也不是矢量的大小(對於該目的,請參閱vector::resizevector::erase ,它修改了矢量大小和內容)。

+1

請不要將這個蹩腳的錯誤ridden網站稱爲「C++文檔」。人們可以認爲這是官方的東西。 – PlasmaHH 2012-01-31 09:46:33

1

除了其他的答案,你不需要reservecopy,因爲assign足以在這裏:

int main() 
{ 
    int l[] = {1,2,3,4}; 
    vector<int> vi; 
    vi.assign(l, l + 4); 

    do_stuff(); 
} 
+3

對於這個問題,'vector'有一個帶兩個迭代器的構造函數。 – 2012-01-31 09:27:43

3

在我看來,你確實想達到什麼是初始化向量元素列表。

std::vector<int> vi {1, 2, 3, 4}; 

如果你的編譯器不支持此語法的是,你可以用好老的範圍內構造:

int a[] = {1, 2, 3, 4}; 
std::vector<int> vi(a + 0, a + 4); 

這是很容易在C++ 11的新列表初始化語法實現如果由於某種原因,你真的要預留空間,然後按元素回來以後,這樣寫:

std::vector<int> vi; 
vi.reserve(4); 
int a[] = {1, 2, 3, 4}; 
std::copy(a + 0, a + 4, std::back_inserter(vi)); // need to #include <iterator> 
+0

全面回答,:)。順便說一句,新的列表初始化語法'std :: vector vi = {1,2,3,4};'不會調用'vector '的copy-ctor? – Alcott 2012-01-31 13:53:41

+0

好點,我將副本列表初始化更改爲直接列表初始化。但它在實踐中可能沒有任何區別。 – fredoverflow 2012-01-31 14:06:27

+0

如果你真的想看透OP的真實意圖,你應該推薦'reserve'加'back_inserter'加'std :: iota' :-) – 2012-01-31 19:29:35