2017-01-23 76 views
-2

(這個問題可以擴展到其他容器)矢量分配管理內存

我可以用一個向量來存儲大量的數據,那麼重要的是要知道如何在C++管理這個容器特別是如果轉讓我沒有太多的記憶。

a)當賦值給一個返回一個向量的函數時,該向量上的數據在賦值之後立即清除,或者保留它直到接收新數據的最後一刻。 b)如果數據被立即銷燬,哪個狀態向量在函數過程中構建新的數據? b)如果數據保留了,這意味着我可以在內存中擁有兩個巨大的向量(舊數據和新數據),直到賦值(返回)爲止?

c)移動語義怎麼樣?它嘗試使用已創建的空間? (如果數據不是立即銷燬喜歡問的第一個問題)

爲了更好地展示它,我寫了一個小程序:

#include <vector> 
#include <string> 

using namespace std; 

vector<string> func2() { 
    vector<string> f2(200000, string(20,'a')); 
    return f2; 
} 

vector<string> func4() { 
    vector<string> f4(400000, string(40,'b')); 
    //Now I have in memory 400000X40 + 200000X20? 
    return f4; 
    //after assignment I know I have just f4 content 
} 

vector<string> func1() { 
    vector<string> f1(100000, string(10,'c')); 
    return f10; 
} 

int main() { 
    vector<string> mVec; 

    mVec = func2(); //Create internally a vector with 20 units string with 20 'b' inside 

    mVec = func4(); //Create internally a vector with 40 units string with 40 'b' inside 

    mVec = func1(); //Create internally a vector with 10 units string with 10 'b' inside 

    return 0; 
} 

如果移動語義真正使用中存在的空間,它是如何工作的時候mVec數據較少,需要分配更多(func2到func4),反之亦然(func4到func1)。

+2

'MVEC = FUNC2()'使用移動分配;在函數中由'f2'分配的內部數據存儲被移交給'mVec'。不執行進一步的分配或複製。與'mVec = func4()'一樣 - 在函數內部分配存儲空間,然後交給'mVec';後者在接受新的所有權之前將其先前的數據解除分配。與'mVec = func1()'相同。 –

+1

更有效的方法可能是通過引用該函數來傳遞向量。這可能會消除一些向量的複製(取決於優化設置和編譯器)。 –

回答

2

當func4()被調用時,就在return語句之前,你肯定有兩個大的向量。而且你將他們記在記憶中。對於c),vector是連續的容器,所以當你創建新的vector時,它將作爲一個整體存儲在內存中,而不是存儲塊1中的一部分和存儲塊127中的另一部分(僅舉一個例子) )。

我的建議是,通過引用使用傳遞向量(將被重寫),並在填充前正確調整它的大小,這樣可以避免整個向量的排列。

代碼示例(優化建議):

#include <vector> 
#include <algorithm> // std::fill 
#include <string> 

using namespace std; 

void func2(vector<string>& vec) { 
    vec.resize(200000); 
    fill(vec.begin(), vec.end(), string(20, 'a')); 
} 

void func4(vector<string>& vec) { 
    vec.resize(400000); 
    fill(vec.begin(), vec.end(), string(40, 'b')); 
} 

void func1(vector<string>& vec) { 
    vec.resize(100000); 
    fill(vec.begin(), vec.end(), string(10, 'c')); 
} 

int main() { 
    vector<string> mVec; 

    func2(mVec); //Create internally a vector with 20 units string with 20 'b' inside 

    func4(mVec); //Create internally a vector with 40 units string with 40 'b' inside 

    func1(mVec); //Create internally a vector with 10 units string with 10 'b' inside 

    return 0; 
}