【转】 申请对齐某种结构体大小的buffer

在大多数状况下,编译器和C库透明地帮你处理对齐问题。POSIX 标明了经过malloc( )calloc( ), 和 realloc( ) 返回的地址对于任何的C类型来讲都是对齐的。在Linux中,这些函数返回的地址在32位系统是以8字节为边界对齐,在64位系统是以16字节为边界对齐的。有时候,对于更大的边界,例如页面,程序员须要动态的对齐。虽然动机是多种多样的,但最多见的是直接块I/O的缓存的对齐或者其它的软件对硬件的交互,所以,POSIX 1003.1d提供一个叫作posix_memalign( )的函数:程序员

/* one or the other -- either suffices */
#define _XOPEN_SOURCE 600
#define _GNU_SOURCE
#include <stdlib.h>
int posix_memalign (void **memptr,
                    size_t alignment,
                    size_t size);
* See http://perens.com/FreeSoftware/ElectricFence/ and http://valgrind.org, respectively.

调用posix_memalign( )成功时会返回size字节的动态内存,而且这块内存的地址是alignment的倍数。参数alignment必须是2的幂,仍是void指针的大小的倍数。返回的内存块的地址放在了memptr里面,函数返回值是0.数组

调用失败时,没有内存会被分配,memptr的值没有被定义,返回以下错误码之一:缓存

EINVAL函数

参数不是2的幂,或者不是void指针的倍数。spa

ENOMEM指针

没有足够的内存去知足函数的请求。内存

要注意的是,对于这个函数,errno不会被设置,只能经过返回值获得。编译器

posix_memalign( )得到的内存经过free( )释放。用法很简单:it

char *buf;
int ret;
/* allocate 1 KB along a 256-byte boundary */
ret = posix_memalign (&buf, 256, 1024);
if (ret) {
    fprintf (stderr, "posix_memalign: %s\n",
             strerror (ret));
    return -1;
}
/* use 'buf'... */
free (buf);

其它和对齐有关的

与对齐有关的问题的范围要超过标准类型的天然对齐和动态存储器地分配。例如,非标准和复杂的类型比标准类型有更复杂的要求。另外,对对齐的关注在给指向不一样类型的指针赋值和使用强转时显得加倍的重要。编译

非标准类型。非标准和复杂的数据类型的对齐比简单的天然对齐有着更多的要求。这里四个有颇有用的方法:

•一个结构的对齐要求是和它的成员中最大的那个类型同样的。例如,一个结构中最大的是以4字节对齐的32bit的整形,那么这个结构至少以4字节对齐。

•结构也引入了填充的须要,用来保证每个成员都符合本身的对齐要求。因此,若是一个char (可能以1字节对齐)后跟着一个int (可能以4字节对齐),编译器会自动地插入3个字节做为填充来保证int以4字节对齐。

程序员有时候排列结构里面的成员-例如,以大小来递减-来是使用做填充的垃圾空间最少。GCC的选项- Wpadded能对这些努力有帮助,由于它使得在编译器偷偷插入填充时产生警告。

•一个联合的对齐和联合里最大的类型同样。

•一个数组的对齐和数组里的元素同样。因此,数组的对齐并不比单单的一个成员严格,这样能使数组里面的全部成员都是天然对齐的。

相关文章
相关标签/搜索