在STL的源码中,或者是其他地方碰到内存对齐的时候 一般会有一个类似于round_up的函数。 一般是像这样子
#define __ALIGN 8 //假设是按照8个字节对齐
static size_t ROUND_UP(size_t bytes)
{
return (((bytes) + __ALIGN - 1) & ~(__ALIGN - 1));
}
在我的QQ群有几个人问过 为什么这样子可以实现 上调对齐。
首先要说的是 这个方法 只适用于 2的N次幂的字节对齐,如果碰到非2的N次幂这个方法是行不通的。
也就是是说 比如是 ........00000000000001000000000.....类似于这样子的割据。
不能让这个存在两个1.
首先解释为什么可以实现对齐。先解释& ~(__ALIGN - 1)。
比如 .....0000100...假设前面有N个0 后面也有M个0 这, 如果
你减去1, 则 形式必然变为 ....00000111...后面会有M个1,而前面则会有N+1个0.
然后对其取反, 则必然变为 ....11111000.....如果任何数 和它进行与运算,则必然将其小于2的N+1次方的那个值 给去除掉。 比如 你按照8个字节对齐,但是这个数是10,首先让10 + 8 -1, 则变为了17. 则必定把小于8个字节的那一截,也就是17 - 16 =1,这个1 这部分减掉, 而变为16.
过程就是这样子, 可以实验一下, 比如 是按照8个字节对齐, 则 8的二进制是
...000001000. 那么首先减去1,则必然变为 ...000000111.然后取反,则变为...111111000.如果你拿任何数 和这个数进行与运算, 则000这个部分 必定会被减掉
这个部分 可能是 1,2,3,4,5,6,7。
如果这个对齐的大小的这个数变为 非2的n次幂的话,则可能是...111..000...11..这种形式,那么最后那个1的高位则不能全部为1 ,如果进行与的时候是什么结果就很难说了。
如果要使用于 每一种情况的话 可以用这样的一个公式。
(X + N -1) - [(x + N -1) % N].
这样就跟你对齐的是不是2次幂无关了。 x为你的实际大小,N为对齐的大小。
道理就是这样子, 希望不懂为什么可以实现的同学能明白。