字節對齊

字節對齊

1. X86結構是小端模式存儲,既數據低位在低存儲地址,數據高位在高存儲地址。例如 short x = 0x3344; 假設x的地址爲 0xBFFFF0F4,那麼0xBFFFF0F4地址裏面存儲的是字節0x44, 0xBFFFF0F5地址裏面存儲的是字節0x33.
2. 爲了使CPU能夠跟快的訪問內存,變量地址和變量長度有關聯,即所謂地址對齊。4字節的int類型變量,其起始地址應位於4字節邊界上,
即起始地址能夠被4整除,也就是地址低2位爲0. N字節對齊就滿足:address &(N-1)== 0。N爲2,4,8,16等2的冪次。討論3字節對齊,5字節對齊沒有什麼意義;
3. 結構體內變量存儲空間,需要看整個結構體內最大變量長度,及各個變量的位置。
struct {
   char  a;
   short b;
   char  c;
}s1;
sizeof(s1) = 6
aa 00 | bb bb | cc 00

struct {
   char  a;
   char  c;
   short b;
}s2;
sizeof(s2) = 4
aa cc | bb bb

struct {
   char  a;
   int b;
   char  c;
}s3;
sizeof(s3) = 12
aa 00 00 00| bb bb bb bb| cc 00 00 00 00

struct {
   char  a;
   char  c;
   int   b;
}s4;
sizeof(s4) = 8
aa cc 00 00 | bb bb bb bb


// 申請align_size字節對齊的存儲空間
void *aligned_malloc(int size, int align_size) {
    // 可以多申請align_size個字節。其中align_size-1字節用來調整對齊,1字節用來記錄和實際分配的起始地址的偏差值。
    void *tempPtr = malloc(size + align_size);               // tempPtr是實際分配地址   
    char offset = align_size - ((int)tempPtr % align_size);  // 和實際分配地址的偏差值,範圍是 [1, align_size]
    char *alignedPtr = (char*)tempPtr + offset;              // tempPtr + offset得到align_size字節對齊的地址空間
    alignedPtr[-1] = offset;                                 // 記錄偏移值在前一個地址字節上
    return (void*)alignedPtr;
}

// 釋放aligned_malloc函數申請到的存儲空間
void aligned_free(void *ptr) {
    char offset = ((char*)ptr)[-1];   // 得到和實際分配地址的偏差值
    free((char*)ptr - offset);        // 得到實際地址
}

 0xzz zz zz zz ... oo vv vv vv ... vv
   |                         |    |
tmpPtr                  |    alignedPtr,函數返回值  
                      存儲offset  
char *alignedPtr = (char*)tempPtr + offset;
char *tempPtr = (char *)alignedPtr - offset;
發佈了40 篇原創文章 · 獲贊 7 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章