2014-04-04 40 views
3

我想用數據填充的(在運行時已知的)量的向量,但元件在(索引,值)對到來,而不是原始的向量訂購。這些指數都保證是唯一的(每個指數從0到n-1的出現恰好一次),所以我想將其保存爲:灌裝在C++外的順序數據

vector<Foo> myVector; 
myVector.reserve(n); //total size of data is known 
myVector[i_0] = v_0; //data v_0 goes at index i_0 (not necessarily 0) 
... 
myVector[i_n_minus_1] = v_n_minus_1; 

這似乎很好地工作在大多數情況;在代碼的最後,所有n個元素都位於向量中的適當位置。然而,一些向量函數不能如願不太工作:

... 
cout << myVector.size(); //prints 0, not n! 

這對我很重要,像size()功能仍能正常工作 - 我可能要檢查,例如,如果所有的元素實際上是插入成功通過檢查是否size() == n。我是否初始化矢量是錯誤的,如果是的話,我應該如何處理這個問題呢?

+3

這是因爲保留不調整矢量大小。你想使用'vector.resize'而不是 – Anycorn

+0

'Foo'默認構造?到目前爲止,三種解決方案都假定它是。否則,可能需要存儲輸入值,然後一次構建所有的Foo。 – MSalters

回答

5

myVector.reserve(n)只是告訴矢量爲n要素分配足夠的存儲,這樣,當你push_back新元素到向量,向量就不必不斷地重新分配更多的存儲空間 - 它可能要做一次這更,因爲它事先不知道你會插入多少個元素。換句話說,你正在通過告訴它不知道的東西來幫助實現矢量實現,並且允許它更高效。

但儲備並不能使該載體n長。向量是空的,事實上像myVector[0] = something這樣的語句是非法的,因爲向量大小爲0:在我的實現中,我得到斷言失敗,「向量下標超出範圍」。這是在Visual C++ 2012上,但我認爲gcc是類似的。

以創建所需長度的矢量根本就

vector<Foo> myVector(n); 

而忽略了reserve

(正如評論指出你一個也叫resize設置向量的大小,但在你的情況下,它是簡單的大小通過爲構造函數的參數。)

+0

我不認爲GCC做了同樣的檢查,因爲G ++並不真正做'_DEBUG'構建像VC++一樣。在我看來,這是VC++擊敗G ++的一個領域。 –

+1

@MooingDuck謝謝你。我認爲gcc在[SGI/stlport](http://www.stlport.org/doc/sgi_stl.html)實現中找到了。我在Windows上使用了這麼多年,直到微軟終於一起行動起來。 SGI stl確實/提供了檢查,您必須打開。 [這是關於在gcc中啓用檢查的答案](http://stackoverflow.com/questions/5594686/gcc-stl-bound-checking)。但正如你所說,你實際上必須手動配置你的makefile或任何具有單獨的DEBUG和RELEASE模式的東西(我確實記得在90年代當我使用* nix devmnt時有這種方式)。 – TooTone

+0

gcc _不相似。範圍檢查默認情況下未啓用(請參閱http://stackoverflow.com/a/5594728) – TooTone

3

需要調用myVector.resize(n)設置(改變)矢量的大小。調用reserve實際上並沒有調整矢量大小,它只是讓它可以稍後重新調整大小而不用重新分配內存。寫過去的矢量結尾(就像你在這裏做的 - 當你寫入它時矢量大小仍然是0)是未定義的行爲。