如何在不调用默认构造函数的情况下创建C样式数组?

时间:2010-02-16 14:01:10

标签: c++ constructor memory-management

我正在编写一个内存管理模板类,我想在其中创建一个固定大小的C风格数组,作为堆。我将对象存储在一个数组中,如下所示:

T v[SIZE];

由于这只是作为可以容纳T对象的堆的角色,我不希望为数组中的每个对象自动调用T默认构造函数。

我想到了像这样定义堆的解决方案:

char v[SIZE * sizeof(T)];

...但这会给我一些对齐问题。

有没有更好的方法来实现这一目标?

ADD:由于我有特殊的运行时要求,因此该类不对全局堆进行任何分配至关重要。

ADD 2:SIZE是一个模板参数,在编译时已知。

6 个答案:

答案 0 :(得分:6)

标准容器使用分配器来分离/解除构造/销毁的分配。标准库提供了一个在堆上分配的分配器。

此代码声明了一个足够大的数组,用于保存SIZE类型的T元素并使用正确的对齐方式:

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

答案 1 :(得分:2)

您要找的是Allocator。可以在此处找到一个很好的概述:http://www.codeproject.com/KB/cpp/allocator.aspx

答案 2 :(得分:0)

很奇怪,但应该有效:

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

此缓冲区将在64位上进行对齐。 但最好通过new分配内存。

在任何情况下,如果size是可变的 - compiller将通过malloc / new(而不是堆栈)动态分配内存。

编辑:您无法使用std::auto_ptr自动释放缓冲区。而是可以使用来自boost的scoped_arr

答案 3 :(得分:0)

我可能会做的是创建一个char数组(就像你已经考虑过的那样),但是为你需要的另一个对象分配足够的空间。然后,您需要编写一些代码来为该空间中的对象找到正确的对齐方式。

对象的最大对齐要求是它自己的大小(否则这些对象的数组不能是连续的,这是必需的)。因此,您选择char缓冲区中第一个地址为sizeof(T)的倍数,并从那里开始您的数组。

答案 4 :(得分:0)

您可以使用结构来处理对齐问题。

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

struct Tbuffer heap[ SIZE ];

答案 5 :(得分:0)

我可能会这样做(在查看EASTL fixed_vector实现之后):

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

...并实现编译器特定的PRAGMA_PRE_ALIGN和PRAGMA_POST_ALIGN宏,插入正确的#pragmas。

不幸的是,此项目无法使用boost和tr1。