转载于:http://www.tuicool.com/articles/q2QrQr,向原文作者表示谢意。
在某些架构上,只有能被指定数(如4,16)整除的内存地址才能够被访问,否则程序会crash,或者出现错误的结果,或者数据的访问变慢。举个例子来说,很多系统都要求interger的地址从偶数开始。opencv2.0以上版本很多指针都是被对齐过的,使指针地址能够被16整除。opencv中的内存一般是通过malloc分配,不能保证都是都能被16整除,此时需要截断,但是剩下的内存要如何维护? CV2.0的这样维护的:在 malloc 是多申请一个指针的空间,这个指针指向 malloc 得到的真实内存地址,只在 free 时使用它。
对于指向任意地址的一个指针,OpenCV中可以使用 template < typename _Tp >_Tp* alignPtr ( _Tp* ptr , int n = sizeof ( _Tp ) ) 函数将其位移到后面最近的一个能整除n的地址,其中n必须是一个2的幂。
alignPtr 只有一行代码,今天看了半天才懂。这一行代码是:
1
2
3
|
template < typename _Tp > static inline _Tp* alignPtr ( _Tp* ptr , int n = ( int )sizeof ( _Tp ) ) { return ( _Tp* ) ( ( ( size_t ) ptr + n - 1 ) & - n ) ;
}
|
开始一直没搞懂 & - n 是干什么,后来经大牛指点意识到n是2的幂,其二进制也就只有一个1,比如n默认为16的时候为00010000,取负数得到111110000,效果是对于2^k,得到一个低k为为0,其他位为1的数,拿这个数(-n)和别的数做与操作,等于把别的数的低k位截没了。这样得到的数必然是2^k的倍数(低k位为0的数必然是2^k的倍数)。这一效果仅对n=2^k成立。