我有一个数组,它被用作类型为T
的对象的基础内存:
char memory[sizeof T];
.
.
.
new(memory) T(whatever);
如何确保T
对象的内存
对齐是正确的?在C++0x中,我可以这样写:
alignas(T) char memory[sizeof T];
但是Visual Studio 2010目前还不支持该特定功能。
我有一个数组,它被用作类型为T
的对象的基础内存:
char memory[sizeof T];
.
.
.
new(memory) T(whatever);
如何确保T
对象的内存
对齐是正确的?在C++0x中,我可以这样写:
alignas(T) char memory[sizeof T];
但是Visual Studio 2010目前还不支持该特定功能。
通常(便携式)解决方案是将内存声明与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
即可。(在Intel和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
的大小)。在搜索 vc++ align
之后,会显示这个页面:使用 __declspec(align(#))
。
__
明显表示的那样,这是一个编译器特定的扩展。 - James Kanzeunion
{
T t;
char memory[sizeof T];
};
应该对齐。
要么在堆上分配内存(这里有对齐保证),要么使用boost::aligned_storage
。