簡體   English   中英

關於填充矢量的不同方式

[英]On different ways of filling a vector

我可以想到三種填充std::vector

假設我們有

vector<int> v(100, 0);

然后我想要它(1,1,1)。 我們可以做的:

v.clear();
v.resize(3, 1);

要么

v = vector<int>(3, 1);

我學到了另一種方法:

vector<int>(3, 1).swap(v); 

第一個問題是:它們中的任何一種都是最好的方法嗎?

第二個問題:假設v在主函數之外聲明。 根據這個答案 ,存儲器將被分配在數據段中。 如果我使用第二種或第三種方法,是否會在堆棧上分配內存?

你怎么用這個任務的向量成員?

std::vector<int> v(100);
v.assign(3, 1); // this is what you should do.

所以,這是差異,我會讓你決定什么是最適合你的情況。

v.clear();
v.resize(3, 1);

在這種情況下,我們將矢量標記為已清除。 它仍保留它分配的任何東西,以容納100個元素(可能超過100個元素所需的空間)。 然后我們添加了3個值為1的項。所有這些都是增加大小計數器並重置3個值,底層內存仍然是相同的大小。

v = vector<int>(3, 1);

這幾乎完全相同,只是創建了一個額外的矢量臨時值而不是存在計數器為0的間歇性位置,然后是具有某些值的3,它簡單地復制計數器大小然后執行類似於memcpy的操作復制3個元素。 為v分配的底層內存大小仍足以容納100個整數。

vector<int>(3, 1).swap(v); 

這個是顯着不同的。 在這種情況下,我們創建一個臨時向量,其中包含3個元素,這些元素都被初始化為1.理論上它仍然可以為100個元素保留足夠的內存,但可能性要少得多。 然后我們將這個向量與我們自己交換,讓臨時被破壞。 這具有額外的好處,即清除我們的舊向量分配的任何額外內存,而不是臨時的。 這種方式的工作方式是兩個向量(我們的v和臨時)交換的不僅僅是計數器和值,它們還交換緩沖區指針。

這是縮小矢量的唯一方法。

首先回答第二個問題: vector將始終為它包含的對象動態分配內存,因此它最終會在堆上。

至於哪種重新分配方法更好,我會說你的第一種或第二種方法使你的意圖最清楚,這是最重要的屬性。

交換將有效地將向量縮小為3個元素。 其他可能不會。

vector<int> v(100);
v.assign(3, 1);
assert(v.size() == 3);
assert(v.capacity() != 3);

v = vector<int>(3, 1);
// Now, v.capacity() is likely not to be 3.

vector<int>(3, 1).swap(v);
assert(v.capacity() == 3);

其他方法不會在內部調整向量。 它仍將在內存中占用100 * sizeof(int)字節,即使size()成員返回3.嘗試顯示v.capacity()以說服自己。

在以前的帖子中沒有提到的一個問題在選擇這些替代方案時很重要。 即,例外安全。 vector<int>(3, 1).swap(v); 有很強的異常安全保障。 形式v = vector<int>(3, 1); 如果以交換方式實施分配,也可能提供此類保證。 第一種選擇是不安全的: v.clear(); v.resize(3, 1); v.clear(); v.resize(3, 1);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM