c语言地址对齐方法

来源:互联网 发布:opengl shader编程 编辑:程序博客网 时间:2024/06/05 18:15

在读nginx的内存分配方面的代码时,发现了其按指定大小(16字节)的数据对齐方式进行内存分配的巧妙方法。

代码如下:

#define NGX_ALIGNMENT 16

 m = ngx_align_ptr(current, NGX_ALIGNMENT);

即从内存为current处开始分配内存,但所分配内存的起始地址必须为NGX_ALIGNMENT的倍数,


如上图所示,current指针指向的地址为0x000000FD不是16字节的倍数,若要从current指针所指向的地址处开始分配内存,则需要找到0x00000100地址处开始分配,那么如何确保无论current指向的地址值为多少,程序都能找到距离current最近,且地址值为16字节倍数的未分配空间作为分配内存的起始地址呢?且看nginx是如何处理的:

#define ngx_align(d, a)     (((d) + (a - 1)) & ~(a - 1))#define ngx_align_ptr(p, a)                                                   \    (u_char *) (((uintptr_t) (p) + ((uintptr_t) a - 1)) & ~((uintptr_t) a - 1))

咋一看没明白,后来自己在程序中做实验才恍然大悟。这里a=16,p为任意地址,d为任意int值

a二进制:   0...00001000(低8位)

a-1二进制:0...00000111

~(a-1)       :1...11111000

假设d=3

d+(a-1)     :0...00001011

(d+(a-1))&~(a-1):

  0...00001011

&1...11111000

= 0...00001000(a)

看到了吧,ngx_align(d,a) 的结果等于a,如果d=17,那么得到的结果是32,无论d为何值,带入式子中得到的结果始终是a的倍数。

同理,ngx_align_ptr(p,a)始终会得到地址比p大,且其值为a的倍数的地址值。

至于原理,大家好好推敲下吧~~