结构体、类等内存字节对齐
来源:互联网 发布:android wifi源码分析 编辑:程序博客网 时间:2024/05/22 03:34
结构体内存对齐,主要是为了CPU能更快速的提取数据
所谓的对齐,指结构体及其成员的内存起始地址address应为要对齐大小X的倍数,
即address = kX
假设 n 为编译器设定的对齐大小, item为结构体中成员类型,那么实际对齐的大小值,
计算如下:
X = min(n, sizeof(item))
-------------------------------------------------------
举例:
例1:
enum ENUM_DATA{IntData, CharData, LongData}; struct Item { char ItemChar1[30]; ENUM_DATA ItemEnum; char ItemChar2[50]; int ItemInt; };
sizeof(struct Item)等于多少?
分析如下:
1.结构体模式模式按成员中最大长度类型进行内存对齐,
struct Item中最大长度类型为int,长度为4
2.假设第一成员的起始地址为0,那么:
ItemChar1 的类型长度为1,根据X = min(n, sizeof(ItemChar1)),即X = min(4, 1) = 1,按1对齐
所以,内存地址空间范围为 0~29, 占30个Byte;
ItemEnum 的类型长度为4,根据X = min(n, sizeof(ItemEnum)),即X = min(4, 4) = 4,按4对齐
由于ItemChar1的结尾内存地址为29,所以下一个成员应该从30开始,
但是30不是4的倍数,往后偏移到32才是4的倍数,
所以ItemEnum的起始内存地址应该是32,
所以,内存地址空间范围为 32~35, 占4个Byte;
ItemChar2 的类型长度为1, X = min(4, 1) = 1
所以,内存地址空间范围为 36~85, 占50个Byte;
ItemInt 的类型长度为4,X = min(4, 4) = 4
起始地址应该是86,但是86非4的倍数,最靠近的88才是4的倍数,
所以起始地址偏移到88的位置
所以,内存地址空间范围为 88~91, 占4个Byte;
3. 由上一步计算得到结构体的内存空间范围为0~91,即大小为92,
而92已经是4的倍数,即所谓的已经对齐
所以该结构体的大小: sizeof(struct Item)等于92
-------------------------------------------------------
例2:
struct A{ int i; int j; short s; char c; };
分析如下:
1.结构体A的最大长度类型int,大小为4
2.假设起始地址为0
i 的类型int, 大小为4, min(4, 4) = 4, 按4对齐,内存地址空间为 0~3
j 的类型int, 大小为4, min(4, 4) = 4, 按4对齐,内存地址空间为 4~7 (4已是4的倍数)
s 的类型short,大小为2,min(4, 2) = 2, 按2对齐,内存地址空间为 8~9 (8已是2的倍数)
c 的类型char, 大小为1, min(4, 1) = 1, 按1对齐,内存地址空间为 10 (10已是1的倍数)
3. 结构体A的地址空间范围为0~10, 大小为11,
但由于要按4对齐,11非4的倍数,最靠近的12才是
所以结构体A的大小应该是12
-------------------------------------------------------
例3:
struct A { char a; int b; double c; char d; };
1. 结构体最大长度类型double,长度为8
2. 假设结构体起始地址为0
a 的类型char大小为1,1小于8,按1对齐,地址空间范围为 0
b 的类型int 大小为4,4小于8,按4对齐,
由于接下来的起始地址1不是4的倍数,所以取4做起始地址
即b的地址空间范围应该是4~7
c 的类型double 大小为8,8等于8,按8对齐,
接着的起始地址应该是8,已经是8的倍数,
所以c的地址空间范围应该是 8~15
d 的类型char大小为1,1小于8,按1对齐,地址空间范围16
3. 结构体地址空间范围0~16, 大小为17,
17不是8的倍数,最靠近的为8的倍数的数应该是24,
所以该结构体大小为24
-------------------------------------------------------
测试:
test.c
#include <stdio.h> struct st_a { int a; char b; char c; }; struct st_b { char b; short c; int a; }; struct st_c { char b; int a; short c; }; int main(int argc, char* argv[]) { struct st_a a; struct st_b b; struct st_c c; printf("st_a size:%d\n", sizeof(a)); printf(" &a:%ld\n", &a.a); printf(" &b:%ld\n", &a.b); printf(" &c:%ld\n", &a.c); printf("st_b size:%d\n", sizeof(b)); printf(" &b:%ld\n", &b.b); printf(" &c:%ld\n", &b.c); printf(" &a:%ld\n", &b.a); printf("st_c size:%d\n", sizeof(c)); printf(" &b:%ld\n", &c.b); printf(" &a:%ld\n", &c.a); printf(" &c:%ld\n", &c.c); return 0; }
gcc -o t test.c
./t
输出:
st_a size:8 &a:140733530861264 &b:140733530861268 &c:140733530861269 st_b size:8 &b:140733530861248 &c:140733530861250 &a:140733530861252 st_c size:12 &b:140733530861232 &a:140733530861236 &c:140733530861240
以上内容出自http://blog.csdn.net/zhaori/article/details/7659268
- char A;
- int B;
- //by www.datahf.net zhangyu
- typedef struct T
- {
- char c; //本身长度1字节
- __int64 d; //本身长度8字节
- int e; //本身长度4字节
- short f; //本身长度2字节
- char g; //本身长度1字节
- short h; //本身长度2字节
- };
- //by www.datahf.net zhangyu
- typedef struct A
- {
- char c; //1个字节
- int d; //4个字节,要与4字节对齐,所以分配至第4个字节处
- short e; //2个字节, 上述两个成员过后,本身就是与2对齐的,所以之前无填充
- }; //整个结构体,最长的成员为4个字节,需要总长度与4字节对齐,所以, sizeof(A)==12
- typedef struct B
- {
- char c; //1个字节
- __int64 d; //8个字节,位置要与8字节对齐,所以分配到第8个字节处
- int e; //4个字节,成员d结束于15字节,紧跟的16字节对齐于4字节,所以分配到16-19
- short f; //2个字节,成员e结束于19字节,紧跟的20字节对齐于2字节,所以分配到20-21
- A g; //结构体长为12字节,最长成员为4字节,需按4字节对齐,所以前面跳过2个字节,
- //到24-35字节处
- char h; //1个字节,分配到36字节处
- int i; //4个字节,要对齐4字节,跳过3字节,分配到40-43 字节
- }; //整个结构体的最大分配成员为8字节,所以结构体后面加5字节填充,被到48字节。故:
- //sizeof(B)==48;
- //by www.datahf.net zhangyu
- #include "stdio.h"
- typedef struct A
- {
- char c;
- int d;
- short e;
- };
- typedef struct B
- {
- char c;
- __int64 d;
- int e;
- short f;
- A g;
- char h;
- int i;
- };
- typedef struct C
- {
- char c;
- __int64 d;
- int e;
- short f;
- char g;
- short h;
- };
- typedef struct D
- {
- char a;
- short b;
- char c;
- };
- int main()
- {
- B *b=new B;
- void *s[32];
- s[0]=b;
- s[1]=&b->c;
- s[2]=&b->d;
- s[3]=&b->e;
- s[4]=&b->f;
- s[5]=&b->g;
- s[6]=&b->h;
- s[7]=&b->g.c;
- s[8]=&b->g.d;
- s[9]=&b->g.e;
- s[10]=&b->i;
- b->c= 0x11;
- b->d= 0x2222222222222222;
- b->e= 0x33333333;
- b->f=0x4444;
- b->g.c=0x50;
- b->g.d=0x51515151;
- b->g.e=0x5252;
- b->h=0x66;
- int i1=sizeof(A);
- int i2=sizeof(B);
- int i3=sizeof(C);
- int i4=sizeof(D);
- printf("i1:%d\ni2:%d\ni3:%d\ni4:%d\n",i1,i2,i3,i4);//12 48 32 6
- }
- 结构体、类等内存字节对齐
- 结构体、类等内存字节对齐
- 详解结构体、类等内存字节对齐
- 详解结构体、类等内存字节对齐
- 详解结构体、类等内存字节对齐
- 解结构体、类等内存字节对齐
- 详解结构体、类等内存字节对齐
- 详解结构体、类等内存字节对齐
- 详解结构体、类等内存字节对齐
- 详解结构体、类等内存字节对齐
- 详解结构体、类等内存字节对齐
- 详解结构体、类等内存字节对齐
- 详解结构体、类等内存字节对齐
- 结构体字节对齐---内存字节对齐(转载)
- [C++基础]内存对齐(字节对齐,结构体对齐)
- 结构体和类的内存字节对齐详解
- 内存中结构体字节对齐
- 内存中结构体字节对齐
- setContentView(R.layout.activity_main) Error解决方法
- Linked List Cycle -- leetcode
- CDH5.3.2中配置运行Spark SQL的Thrift Server
- Spark下实现LDA+SVM的文本分类处理
- Andorid-15k+的面试题。
- 结构体、类等内存字节对齐
- 时间序列数据评估
- IOS 文件读写常用的2中方法
- Java分布式应用技术架构介绍
- 重装后只有C盘,资料丢失
- 实用好习惯,让一个人每天进步
- DEMO
- 第十周项目 3 日期时间类
- Twister—迭代MapReduce