我正在编写一个内存管理模板类,我想在其中创建一个固定大小的C风格数组,作为堆。我将对象存储在一个数组中,如下所示:
T v[SIZE];
由于这只是作为可以容纳T对象的堆的角色,我不希望为数组中的每个对象自动调用T默认构造函数。
我想到了像这样定义堆的解决方案:
char v[SIZE * sizeof(T)];
...但这会给我一些对齐问题。
有没有更好的方法来实现这一目标?
ADD:由于我有特殊的运行时要求,因此该类不对全局堆进行任何分配至关重要。
ADD 2:SIZE是一个模板参数,在编译时已知。
答案 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。