分配一段長度爲BUFFER_SIZE個位元組的記憶體,首地址要求n位元組對齊
這個問題的關鍵是要求首地址按照n位元組對齊。爲了方便分析,我們以8位元組對齊爲例
也就是當初始首地址給定爲(0,8]之間,我們要將首地址調整到8位元組處;當初始首地址在(8,16]之間,我們要將首地址調整到16位元組處.....依此類推。總而言之,就是右對齊,與記憶體地址的增長方向相同。
爲了確定首地址,封裝了一個宏,如下:
#define ADDR_ALIGN_BASE 8
#define ADDR_ALIGNED(addr) (((addr) + ADDR_ALIGN_BASE - 1) & (0xfffffff8))
輸入addr是一個隨意給定的地址,返回一個8位元組對齊(右對齊)的地址
總共分爲兩步:
先解釋幾個問題:
1.爲什麼是加上,而不是減去;爲什麼加上的是7個位元組,而不是8位元組呢?
加上是和記憶體的增長方向相同,以避免覆蓋掉之前的數據(在此預設給定的addr地址之前的記憶體空間已經使用,addr地址之後的空間沒有使用)
加上7個位元組是爲了避免空間浪費。舉一個極端的例子,比如給定的地址就是8位元組處,已經對齊,如果加上8個位元組的話最終得到的對齊地址就是16位元組處,雖然說也是基於8位元組對齊,但是8-16位元組處的空間浪費掉了。
2.爲什麼要和0xfffffff8與?
0xfffffff8轉換成二進制就是11111111111111111111111111111000,也就是後面跟着三個零,2的3次方正好是8。最終目的就是得到一個能被8整除的地址。
爲了方便理解,舉兩個例子說明
1.給定地址爲7位元組處,要求轉換爲8位元組對齊的地址
第一步,7+(8-1) = 14(0x0000000e)
第二步,(0x0000000e)&(0xfffffff8)= 8
結果爲8位元組處
2.給定地址爲9位元組處,要求轉換爲8位元組對齊的地址
第一步,9+(8-1) = 16(0x00000010)
第二步,(0x00000010)&(0xfffffff8)= 0x10(16)
結果爲16位元組處
ref:
http://www.manongjc.com/detail/10-hgdukjoorgrtexk.html
https://www.jianshu.com/p/eb497ea3f551
https://baijiahao.baidu.com/s?id=1642532556639906097&wfr=spider&for=pc