2010-02-16 30 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在这个项目中是不可能的。

相关问题