2012-05-30 23 views
7

我已經讓我的腦袋圍繞着C++幾個月,並且有 被谷歌指令堆棧溢出,大部分時間爲 用於C++查詢。我注意到經常對 「爲什麼不使用矢量」這一類型的說明,並且受到啓發就是爲了做到這一點。不像陣列的C++向量

所以,主要是爲了獲得自動內存釋放, 的小優點,並且能夠編寫用於排序的類型比較函數。 我將一個指向數組的指針切換爲一個矢量。 現在我覺得(不正確地似乎),其載體可以或多或少是陣列中使用 ,因此我初始化正是如此:

cluster clusters[LOTS]; 
vector<cluster *> pclust; 
pclust.reserve(numClust); 
for (int i=0; i<numClust; ++i) 
    pclust[i] = clusters + i; 

從編譯器沒有抱怨。 然後一段時間後,我需要對集​​羣對象的某些 屬性上的向量進行排序。所以:

std::sort(pclust.begin(), pclust.end(), ClusterCompareNumSegs); 

再次沒有問題編譯。除矢量不 得到排序。事實證明,vector.size()爲零, ,當然還有我的初始化應該已經

pclust.push_back(clusters + i); 

現在,這是很容易解決,但我很困惑,因爲最初 不正確的分配是工作。我通過 成功迭代向量 - 使用數組語法,就像這樣:

for (clustind=0; clustind < numClust; ++clustind) {<br> 
    cluster *cl = pclust[clustind]; 
    ...happily access *cl... 

而這一切都工作得很好。所以我只是想知道發生了什麼。 大概在我最初的任務中,我試圖訪問尚未在向量中的元素(我試圖將它們放入), ,並且向量拋出了我忽略的異常。 但是,當參考位置時,指針 在那裏。任何人都可以提供啓發嗎?

+2

標準庫是相當廣闊的,並沒有什麼特別歡迎對初學者,我建議你至少在容器類型(http://en.cppreference.com/w/cpp)閱讀文檔 - 它會爲你節省很多痛苦。 – cmannett85

+0

只是爲了重申一下,我的代碼現在都是固定的,但我只是想知道 – bandjalong

+0

..如果任何人都可以解釋,而運算符[]工作得很好,即使沒有改變大小。編譯器(gcc)實現矢量也許幸運嗎? – bandjalong

回答

11

vector::reserve不改變你的向量的大小,它仍然只包含它創建的0元素。它所做的就是確保該矢量可能不需要重新分配就可以保存numClust。見here

你想要的是要麼聲明向量有大小

vector<cluster *> pclust(numClust); 

resize the vector

pclust.resize(numClust); 
+0

我稱爲保留的原因是因爲我知道要添加多少元素,並且希望有足夠的空間以便在添加元素時不需要重新分配(我真的希望數組的效率和思想向量接近足夠)。 – bandjalong

+0

..但是你是否說調用調整大小會允許我使用數組語法對它們進行初始化?如果這樣做很好(我擔心數組語法不能用作左值,這會很麻煩)。但我仍然想知道爲什麼數組已初始化,因爲數據在那裏,但尚未初始化,該向量認爲它的大小爲零... – bandjalong

+0

@ user1425406:'operator []'不會將元素添加到一個向量。它返回對現有元素的引用。 'resize()'確實將元素添加到矢量中。小心「初始化」這個詞。在C++中有非常具體的含義,對於類型來說也就是調用構造函數。 'a [3] = b'調用賦值操作符,這需要左手已經初始化的對象。 – MSalters

5

std::vector::reserve請求所分配的存儲空間的容量的元素矢量容器至少足以容納n個元素。它不調整矢量大小,這就是std::vector::resize所做的。

pclust.reserve(numClust);替換爲pclust.resize(numClust);

或者,您可以刪除pclust.reserve(numClust);調用並將此向量的構建更改爲:vector<cluster *> pclust(numClust);,這會得出相同的結果。

我也建議你看一下這個問題:std::vector reserve() and push_back() is faster than resize() and array index, why? :)

+0

通過調整大小來替換保留區並不能解決確保正確分配內存量的權利(我認爲),而且不會再有更多的內存(這是我的想法,也是避免重新分配)。我不能調用構造函數的大小,因爲我不知道調用構造函數時的大小。但是,沒關係,現在都很好,我只是不明白爲什麼我的(錯誤)代碼和它一樣工作。 – bandjalong

+0

@ user1425406:爲什麼'resize'分配的內存比'reserve'多?這兩者之間的區別在於,調整大小不僅「保留」內存,而且構建這些元素,因此您可以通過使用at()或'[]'來訪問它們。如果您正在尋找性能,那麼使用'reserve' +'push_back'。 – LihO

+0

我認爲保留保證不分配超過指定的數額,並且調整大小不是。但現在看,我不明白我爲什麼這麼想。所以好吧,調整大小會起作用(但是正如你所建議的那樣,reserve和push_back是最快的)。基本上我希望編譯器能夠生成與初始化數組時相同的代碼。 – bandjalong

0

運營商[]與向量返回用於參考元素的索引位置。但是,你還沒有用任何值初始化矢量,所以它是空的。

雖然你做了pclust.reserve(numClust),但它只告訴矢量的大小很快就會改變,並且它在不改變矢量大小的情況下分配存儲空間。

+0

但是,這是神祕的,[]工作(在時尚之後),我把所有這些初始值(而矢量保持在零的大小),隨後成功檢索和解除引用。 – bandjalong

0
cluster clusters[LOTS]; 
vector<cluster *> pclust(numClust); 
for (int i = 0; i < numClust; ++i) 
    pclust[i] = clusters + i; 

但這意味着您仍然在使用數組來存儲羣集。 難道你不能讓clusters一個載體?

vector<cluster> clusters(LOTS); 
+0

是的,我可以,但我不能看到一個優勢,它是一個載體(我無法那種無論如何,我需要序列化數據結構是序號爲它...)。 – bandjalong