2010-02-16 80 views
5

我正在寫一個內存管理模板類,我想在其中創建一個固定大小的C風格的數組,以充當堆。我一直存儲在數組中的對象是這樣的:如何在不調用默認構造函數的情況下創建C風格的數組?

T v[SIZE]; 

由於這隻會作用,作爲一個堆,可容納T對象,我不希望得到自動調用中的每個對象的T默認構造函數陣列。

我想到了解決這樣定義堆:

char v[SIZE * sizeof(T)]; 

...但是這會給我對齊問題。

有沒有更好的方法來實現這一目標?

地址:由於我有特殊的運行時間要求,所以這個類不必對全局堆進行任何分配。

ADD 2:SIZE是一個模板參數,在編譯時已知。

+0

什麼時候你打算如果不是,那麼T的構造函數被調用?手動分配數組項目,還是使用自己的新操作符? – Elemental 2010-02-16 14:06:42

+0

你可以使用malloc,但是,而且,但是 - 你不應該需要這種功能。 – Drakosha 2010-02-16 14:09:09

+0

T構造函數將被手動調用。這部分不是問題。 – 2010-02-16 14:14:31

回答

6

標準容器使用分配器來分配/從構建/銷燬分離。標準庫提供了一個在堆上分配的分配器。

此代碼聲明大到足以容納T類型的SIZE元件具有正確allignment的數組:

typedef typename std::tr1::aligned_storage<sizeof(T),std::tr1::alignment_of<T>::value>::type aligned_storage; 
aligned_storage array[SIZE]; 

使用std::allocator溶液不能被用於聲明在堆棧上的陣列,並作爲標準容器需要自定義分配器不保持狀態,自定義分配器也不能用於在堆棧上分配。

如果你的編譯器不支持std::tr1::alignment_of,你可以用boost::alignment_of來代替。

+0

我意識到這可能是最好的解決方案。不幸的是,我被阻止使用tr1或boost。謝謝 – 2010-02-17 10:17:12

+0

在這種情況下,你可以看看boost :: alignment_of是如何工作的 - 它在概念上相當簡單,只是一個大小小於等於(T)的整數類型的聯合包裝。難點在於提供不同平臺上不同尺寸類型的列表。如果你只處理一個或兩個編譯器,它應該很簡單。 – 2010-02-17 10:44:15

+0

問題是,諸如aligned_storage之類的功能需要一些編譯器支持或至少某些不屬於該標準的編譯器和機器特定的保證。這就是爲什麼我會繼續使用boost :: aligned_storage(所以我不必處理實現細節)。 – sellibitze 2010-02-17 12:12:23

2

你在找什麼叫做Allocator。一個很好的概述可以在這裏找到:http://www.codeproject.com/KB/cpp/allocator.aspx

+0

我不確定我可以在這種情況下應用它。管理者對象不做任何分配並且可以放在堆棧上是非常重要的。 – 2010-02-16 14:10:56

0

怪異,但應該工作:

long long v[size * sizeof(T)/sizeof(long long)+1]; 

該緩衝區將在64位被神韻:。 但更好的將由new分配內存。

在任何情況下,如果size是變量 - compiller將通過malloc/new(而不是堆棧)動態地分配內存。

編輯:你不能使用std::auto_ptr自動緩衝區。可以使用scoped_arr from boost可以使用

+0

謝謝。我應該提到,尺寸也是一個模板參數。 – 2010-02-16 14:16:38

+3

你不能使用'std :: auto_ptr'來釋放一個動態分配的數組,因爲它使用'delete'而不是'delete []'。 – 2010-02-16 14:23:38

+0

@Joe Gauterin:極好的一點。 Boost的scoped_arr和shared_arr可以用於此目的。 – 2010-02-16 15:13:15

0

我可能要做的是創建一個char數組(大概就像你已經考慮的那樣),但是爲一個多於一個的對象分配足夠的空間。然後,您需要編寫一些代碼來找到該空間中對象的正確對齊方式。

對象的最大對齊需求是其自身的大小(否則這些對象的數組不能連續,這是必需的)。因此,你選擇char-buffer中sizeof(T)的倍數的第一個地址,然後從那裏開始你的數組。

0

您可以使用結構來處理對齊問題。

struct Tbuffer { char data_[ sizeof(T) ]; } 

struct Tbuffer heap[ SIZE ]; 
+0

你真的想從堆棧中獲得這個權利嗎? – 2010-02-16 21:41:26

+0

不行,我想? – 2010-02-17 09:57:22

+0

爲什麼不呢?我經常用這個。 – 2010-02-18 21:51:55

0

我怎麼可能會做(看好EASTL fixed_vector實施後):

PRAGMA_PRE_ALIGN(sizeof(T)) char[SIZE * sizeof(T)]; PRAGMA_POST_ALIGN(sizeof(T)) 

...和實施具體的編譯器和PRAGMA_PRE_ALIGN宏PRAGMA_POST_ALIGN,即插入正確的編譯指示。

不幸的是,boost和tr1在這個項目中是不可能的。