首页 > 代码库 > 字节对齐
字节对齐
字节对齐
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;
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;
字节对齐
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。