5

我有一个数组,用作类型对象的底层内存T

char memory[sizeof T];
.
.
.
new(memory) T(whatever);

如何确保对象memory正确对齐T?在 C++0x 中,我只能说:

alignas(T) char memory[sizeof T];

但 Visual Studio 2010 尚不支持该特定功能。

4

4 回答 4

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就够了。(在 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)。

请注意,标准没有正式保证这些。但它会在实践中发挥作用。

于 2011-08-05T16:31:34.523 回答
5

谷歌搜索vc++ align显示此页面:使用__declspec(align(#)).

于 2011-08-05T16:08:06.330 回答
3

如果 T 是标准布局并且联合是良好的,那么

union
{
   T t;
   char memory[sizeof T];
};

应该对齐。

于 2011-08-05T16:43:15.597 回答
2

在堆上分配内存(具有对齐保证)或使用boost::aligned_storage.

于 2011-08-05T16:19:50.730 回答