在C的世界中,因为要考虑效率问题,所以在申请一段内存的时候,需要根据寄存器的宽度进行对齐。因此,对于32位的程序,按照4字节对齐;对于64位的程序,则按照8字节对齐。
o 下面使用位运算给出实现:
1 #define align4(x) (((((x)-1)>>2)<<2)+4) 2 #define align8(x) (((((x)-1)>>3)<<3)+8)
o 用Python代码简单实现并验证一下:
1 #!/usr/bin/python 2 3 """ alignN(x) is often used by malloc(3C), here is a simple implementation """ 4 5 import sys 6 7 def align4(x): return (((((x)-1)>>2)<<2)+4) 8 def align8(x): return (((((x)-1)>>3)<<3)+8) 9 10 def main(argc, argv): 11 if argc != 2: 12 return 1 13 for i in range(0, int(argv[1])+1): 14 print "%2d %2d %2d" % (i, align4(i), align8(i)) 15 return 0 16 17 if __name__ == '__main__': 18 argc, argv = len(sys.argv), sys.argv 19 sys.exit(main(argc, argv))
o 测试
$ ./foo.py 16 0 0 0 1 4 8 2 4 8 3 4 8 4 4 8 5 8 8 6 8 8 7 8 8 8 8 8 9 12 16 10 12 16 11 12 16 12 12 16 13 16 16 14 16 16 15 16 16 16 16 16
最后,以8字节对齐讲解其实现原理。
设x = 8 * a + b, 0 <= b <= 7, x为申请的内存size。
(1) 如果b=0, 则x = 8 * a。因此,x的低3位不需要被清零;
(2) 如果1<=b<=7, 则x应该为8 * (a+1)。因此,直接将x的低3位清零并加8即可,那么x = (x >> 3) << 3 + 8;
为统一(1)和(2), 分两步走:
1. x = x - 1; /* if x mod 8 == 0, 则新x的低3位为7; if x mod 8 == 1, 则新x的低3位为0 */
2. x = (x >> 3) << 3 + 8; /* 将低3位清零,然后统一加上8,搞定! */
扩展阅读: