如何确定C99中所需的最大对齐

时间:2016-07-08 16:04:27

标签: c c99 memory-alignment

是否有一种可移植的方式只依赖于C99标准提供的方法来找出任何数据类型所需的最大对齐。

与C ++ 11中的maxalign_t类似。

我目前正在做的是计算lcmintlong intlong long int的对齐的最小公倍数(double), void *size_t是确定对齐的最佳方法。

更新 我目前需要这个来实现malloc的包装器,它在内存块的开头存储元数据,并返回一个地址高于malloc返回的地址的指针。

2 个答案:

答案 0 :(得分:2)

这并不是一个很好的方法,这就是C11引入maxalign_t的原因。但是,我无法想象一个普通系统,其中对齐要求高于intmax_t的类型存在,所以当maxalign_t不可用时,您也可以使用它并获得99%系统的正确答案。

答案 1 :(得分:0)

您可以通过分配几个块并查看每个块是否在16,8或4字节边界上对齐来凭经验确定支持的最大对齐。

bool GetConsistentAlignment( std::size_t alignment )
{
    const unsigned int chunkCount = 16;
    void * places[ chunkCount ];
    memset( places, 0, sizeof(places) );
    bool consistent = true;

    for ( unsigned int ii = 0;  ii < chunkCount; ++ii )
    {
        const std::size_t size = 1024 + rand() % 4096;
        void * chunk = malloc( size );
        places[ ii ] = chunk;
    }

    for ( unsigned int ii = 0;  ii < chunkCount; ++ii )
    {
        void * chunk = places[ ii ];
        const std::size_t place = reinterpret_cast< const std::size_t >( chunk );
        if ( place % alignment != 0 )
        {
            consistent = false;
        }
        free( chunk );
    }

    return consistent;
}

std::size_t GetMaxSupportedAlignment()
{
    static std::size_t maxAlignment = 0;

    if ( maxAlignment == 0 )
    {
        std::srand( std::time( 0 ) );
        std::size_t alignment = 64;
        while ( alignment > 1 )
        {
            const bool isConsistentAlignment = GetConsistentAlignment( alignment );
            if ( isConsistentAlignment )
            {
                break;
            }
            alignment /= 2;
        }
        maxAlignment = alignment;
    }

    return maxAlignment;
}

调用GetMaxSupportedAlignment()将在64位操作系统上返回8,在许多32位系统上返回4。