2016-08-22 84 views
0

所以我寫一個類,它有一維數組和二維數組,我動態地構造分配使用std :: vector來動態分配2d數組?

class Foo{ 
int** 2darray; 
int * 1darray; 
}; 

Foo::Foo(num1, num2){ 

2darray = new int*[num1]; 
for(int i = 0; i < num1; i++) 
{  
    array[i] = new int[num2]; 
} 
1darray = new int[num1]; 
} 

那麼我將不得不刪除二維數組中的每一個一維數組,每個數組在析構函數中,對嗎? 我想使用std :: vector不必這樣做。這樣做有什麼缺點嗎? (編譯速度較慢等)?

TL; DR:什麼時候使用std :: vector來動態分配數組,而不需要在運行時調整大小?

+5

恕我直言*動態分配數組* *等於'std :: vector'。我儘量遠離手動內存分配。 – NathanOliver

+0

總是使用'std :: vector',除非你真的知道在編譯時你的數組有多大。即使那樣,你可能也想使用一個標準容器(如果你想擁有一組標誌,就說一個bitset)。對於大多數使用情況,運行時不改變大小的'std :: vector '與'Type []'相同。 – 2016-08-22 13:09:52

+0

順便說一句,不要使用向量矢量,也不要使用2D矢量。 – Ped7g

回答

3

vector適用於絕大多數用途。手動調整的方案應首先嚐試調整分配器,然後才能修改容器。內存管理的正確性(以及一般的程序)價值很大,遠遠超過了編譯時間的增加。

換句話說,vector應該是你的出發點,而直到你發現它不理想,你不應該在意別的。

作爲附加改進,請考慮使用1維vector作爲後端存儲並僅提供2維索引視圖。這種情況可以改善緩存局部性和整體性能,同時也可以使複製整個結構的操作變得更容易。


的那vector接受兩個模板的參數,所述第二默認爲給定類型的一個標準的分配器。

+0

感謝您的洞察力。你能解釋何時使用分配器? – kassio

+2

@qeia如果你需要問什麼時候,你不需要定製它。 –

2

因爲vector保證連續的內存不應該有任何缺點。但是,如果大小是固定的,C++ 11可也許其他選項中的array

  • 它不允許調整
  • 取決於如何vector初始化防止再分配
  • 大小是硬編碼在說明中(模板參數)。有關更詳細的描述,請參閱Ped7g註釋
+1

謹慎解釋爲什麼downvote? –

+0

不是downvoter,只是一個評論者:「保證」,而不是「保證」。另外,請解釋您關於數組作爲更好選項的合格聲明。 – 2016-08-22 13:15:13

+2

@Boris:因爲對於'std :: array',大小在指令中是硬編碼的(size是模板參數)。大多數時候IMO是邊際收益,如果被許多不同大小的數組使用,代碼膨脹可能會造成更多的損害。但這只是我的無保留的假設(你必須剖析實際的代碼以對此有任何合格的意見:))。但對於二維數組(編寫爲1D),一個硬編碼的'* rowsize'可以帶來一些優勢,特別是對於2個尺寸的冪(在現代x86上,它很可能不會有問題,任意'mul'都可以)。 – Ped7g

0

二維數組不是一個指針數組。 如果你這樣定義它,每一行/列可以有不同的大小。 此外,內存中的元素不會按順序排列。 這可能會導致性能下降,因爲預取程序無法很好地預測您的訪問模式。 因此,建議不要將std :: vectors嵌套在eachother中以模擬多維數組。 更好的方法是通過提供自定義訪問方法將連續的內存塊映射到多維空間。通過返回其具有對數據的訪問的索引和尺寸的VectorView http://fiddle.jyt.io/github/3389bf64cc6bd7c2218c1c96f62fa203

#include<vector> 

template<class T> 
struct Matrix { 
    Matrix(std::size_t n=1, std::size_t m=1) 
    : n{n}, m{m}, data(n*m) 
    {} 

    Matrix(std::size_t n, std::size_t m, std::vector<T> const& data) 
    : n{n}, m{m}, data{data} 
    {} 

    //Matrix M(2,2, {1,1,1,1}); 

    T const& operator()(size_t i, size_t j) const { 
    return data[i*m + j]; 
    } 

    T& operator()(size_t i, size_t j) { 
    return data[i*m + j]; 
    } 

    size_t n; 
    size_t m; 
    std::vector<T> data; 
    using ScalarType = T; 
}; 

可以實現操作符[]:

可以在瀏覽器中進行測試。