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;