我有一个数组,用作T
类型对象的底层内存:
char memory[sizeof T];
.
.
.
new(memory) T(whatever);
如何确保memory
对象T
正确对齐?在C ++ 0x中我可以说:
alignas(T) char memory[sizeof T];
但Visual Studio 2010尚不支持该特定功能。
答案 0 :(得分:10)
通常的(可移植)解决方案是将内存声明与T
中需要最多对齐的任何内置类型联合起来。
最简单的方法是使用所有可能的联合
候选:
union MaxAlign
{
int i ;
long l ;
long long ll ;
long double ld ;
double d ;
void* p ;
void (* pf)() ;
MaxAlign* ps ;
} ;
union
{
MaxAlign dummyForAlignment;
unsigned char memory[sizeof(T)];
} rawT;
我还没有听说过,更不用说相遇了,上面的机器
不够。通常,只需double
即可。 (绝对是
在英特尔和Sparc上足够了。)
在某些极端情况下,这会导致分配更多内存
必要的,例如如果T
仅包含一个或两个char
。大部分的
时间,这真的没关系,并不值得担心,但如果
它是,可以使用以下内容:
namespace MyPrivate {
template< typename T, bool isSmaller >
struct AlignTypeDetail ;
template< typename T >
struct AlignTypeDetail< T, false >
{
typedef T type ;
} ;
template< typename T >
struct AlignTypeDetail< T, true >
{
typedef char type ;
} ;
template< typename T, typename U >
struct AlignType
{
typedef typename AlignTypeDetail< U, (sizeof( T ) < sizeof( U )) >::type
type ;
} ;
}
template< typename T >
union MaxAlignFor
{
typename MyPrivate::AlignType< T, char >::type c ;
typename MyPrivate::AlignType< T, short >::type s ;
typename MyPrivate::AlignType< T, int >::type i ;
typename MyPrivate::AlignType< T, long >::type l ;
typename MyPrivate::AlignType< T, long long >::type ll ;
typename MyPrivate::AlignType< T, float >::type f ;
typename MyPrivate::AlignType< T, double >::type d ;
typename MyPrivate::AlignType< T, long double >::type ld ;
typename MyPrivate::AlignType< T, void* >::type pc ;
typename MyPrivate::AlignType< T, MaxAlign* >::type ps ;
typename MyPrivate::AlignType< T, void (*)() >::type pf ;
} ;
在这种情况下,MaxAlignFor<T>
永远不会大于T
(并且要有足够的对齐,因为所需的对齐方式会
永远不要大于T
)的大小。
请注意,标准并未正式保证这一点。但它 将在实践中工作。
答案 1 :(得分:5)
通过Google搜索vc++ align
显示this page:使用__declspec(align(#))
。
答案 2 :(得分:3)
如果T是标准布局并且联合格式良好,那么
union
{
T t;
char memory[sizeof T];
};
应该对齐。
答案 3 :(得分:2)
分配堆上的内存(具有对齐保证)或使用boost::aligned_storage
。