【学习笔记】内存对齐
2015-05-19 08:57
323 查看
初始化:
struct student{
int num ;
char *name ;
int grade ;
};
int main(void)
{
struct s arr[]={
{ 1 , "chenxi" , 100 } , //方式1:按顺序
{ .name = "chenxi" , .num = 1 , .grade = 100 } ,// 方式2:成员名字前加个 .
};
int i = 0;
for(i=0 ; i<2; ++i)
{
printf("student's name is %s,num is %d ,grade is %d", arr[i].name , arr[i].num , arr[i].grade);
}
return 0;
}
使用初始化方式2可以不用对结构的内存分布作假设,一般在使用别人结构体的时候应以这种方式初始化。
结构体内存对齐:
sturct test{
char a ;
int b ;
};
struct test orange ;
结构体必须先实例一个对象才占内存空间 。
结构体中的成员,每一个成员的地址必须是该成员类型大小的整数倍。
结构体中的成员,只能从偏移量为其大小的倍数的地址开始存放。
结构体共占用的内存空间,是其成员中的基础类型的最大值的倍数。
sizeof(orange) = 8 ; char占第一个字节,int只能从偏移量为4的倍数开始存放,char后3个字节被“浪费”,所以这个结构体占8个字节。
枚举类enum 默认占4个字节(int),即使不实例一个对象也占 。
指针大小 = (系统位数 / 8 )个字节 ;
结构体大小的计算方法和步骤(转自:http://blog.csdn.net/kingskyleader/article/details/7926996)
1)将结构体内所有数据成员的长度值相加,记为sum_a;
2)将各数据成员为了内存对齐,按各自对齐模数而填充的字节数累加到和sum_a上,记为sum_b。对齐模数是#pragma pack指定的数值以及该数据成员自身长度中数值较小者,该数据相对起始位置应该是对齐模式的整数倍。
3)将和sum_b向结构体模数对齐,该模数是【#pragma pack指定的数值】(未指定#pragma
pack时,系统默认的对齐模数(32位系统为4字节,64位为8字节))和【结构体内部最大的基本数据类型成员】长度中数值较小者。结构体的长度应该是该模数的整数倍。
结构体中的位段:
struct test{
int a:8 ;
char b ;
int c ;
};
struct test apple ;
sizeof(apple) = 8 。
因为 a 中使用了前8位 , 还有 24位可以使用 , b 只占8位 , 所以在 a 剩余的空间中放入b 。
struct test{
int a:9;
char b ;
int c:8 ;
};
struct test banana ;
sizeof(banana)大小为4字节,一个int有32位,三个成员一共占用了25个位。
struct test{
int a:9 ;
char b ;
int c:9 ;
};
struct test juice ;
sizeof(juice) 的大小为 8 字节, a占了前9位 ,b占了16-24位 ,剩余8位不足以存放c ,所以再申请了4个字节存放c。
struct test{
int a:8 ;
char b ;
char c ;
int d:7
};
struct test melon
sizeof(melon) 大小为4字节 。
struct packed_struct
{
unsigned int f1 :1;
unsigned int f2 :1;
unsigned int f3 :1;
unsigned int type :4;
unsigned int index :7;
};
表示:标志 f1, f2, f3 分别只需要 1 位。变量 type 只需要 4 位, 而变量index只需要7位,总共14位,不超过2个字节。
sizeof(struct packd_struct)为4,奇怪,为什么不是2或3而是4呢?
其实,哪怕是struct foo {unsigned int f1 :1},也会占用4个字节呢,与unsigned int相同。
总结一下:当位段出现在结构定义中时, 至少会占用等同于unsigned int类型的空间,当所有的位段之和超出,分配另一个unsigned int空间。
另外:unsigned char或者其他类型不必考虑。
三.何时位段会失效
例如:
struct bits
{
unsigned int f1:1;
int word;
unsigned int f3:1;
};
按照内存对齐的规则,位段声明会无效,上述sizeof(struct bits)为12!
struct student{
int num ;
char *name ;
int grade ;
};
int main(void)
{
struct s arr[]={
{ 1 , "chenxi" , 100 } , //方式1:按顺序
{ .name = "chenxi" , .num = 1 , .grade = 100 } ,// 方式2:成员名字前加个 .
};
int i = 0;
for(i=0 ; i<2; ++i)
{
printf("student's name is %s,num is %d ,grade is %d", arr[i].name , arr[i].num , arr[i].grade);
}
return 0;
}
使用初始化方式2可以不用对结构的内存分布作假设,一般在使用别人结构体的时候应以这种方式初始化。
结构体内存对齐:
sturct test{
char a ;
int b ;
};
struct test orange ;
结构体必须先实例一个对象才占内存空间 。
结构体中的成员,每一个成员的地址必须是该成员类型大小的整数倍。
结构体中的成员,只能从偏移量为其大小的倍数的地址开始存放。
结构体共占用的内存空间,是其成员中的基础类型的最大值的倍数。
sizeof(orange) = 8 ; char占第一个字节,int只能从偏移量为4的倍数开始存放,char后3个字节被“浪费”,所以这个结构体占8个字节。
枚举类enum 默认占4个字节(int),即使不实例一个对象也占 。
指针大小 = (系统位数 / 8 )个字节 ;
结构体大小的计算方法和步骤(转自:http://blog.csdn.net/kingskyleader/article/details/7926996)
1)将结构体内所有数据成员的长度值相加,记为sum_a;
2)将各数据成员为了内存对齐,按各自对齐模数而填充的字节数累加到和sum_a上,记为sum_b。对齐模数是#pragma pack指定的数值以及该数据成员自身长度中数值较小者,该数据相对起始位置应该是对齐模式的整数倍。
3)将和sum_b向结构体模数对齐,该模数是【#pragma pack指定的数值】(未指定#pragma
pack时,系统默认的对齐模数(32位系统为4字节,64位为8字节))和【结构体内部最大的基本数据类型成员】长度中数值较小者。结构体的长度应该是该模数的整数倍。
结构体中的位段:
struct test{
int a:8 ;
char b ;
int c ;
};
struct test apple ;
sizeof(apple) = 8 。
因为 a 中使用了前8位 , 还有 24位可以使用 , b 只占8位 , 所以在 a 剩余的空间中放入b 。
struct test{
int a:9;
char b ;
int c:8 ;
};
struct test banana ;
sizeof(banana)大小为4字节,一个int有32位,三个成员一共占用了25个位。
struct test{
int a:9 ;
char b ;
int c:9 ;
};
struct test juice ;
sizeof(juice) 的大小为 8 字节, a占了前9位 ,b占了16-24位 ,剩余8位不足以存放c ,所以再申请了4个字节存放c。
struct test{
int a:8 ;
char b ;
char c ;
int d:7
};
struct test melon
sizeof(melon) 大小为4字节 。
struct packed_struct
{
unsigned int f1 :1;
unsigned int f2 :1;
unsigned int f3 :1;
unsigned int type :4;
unsigned int index :7;
};
表示:标志 f1, f2, f3 分别只需要 1 位。变量 type 只需要 4 位, 而变量index只需要7位,总共14位,不超过2个字节。
sizeof(struct packd_struct)为4,奇怪,为什么不是2或3而是4呢?
其实,哪怕是struct foo {unsigned int f1 :1},也会占用4个字节呢,与unsigned int相同。
总结一下:当位段出现在结构定义中时, 至少会占用等同于unsigned int类型的空间,当所有的位段之和超出,分配另一个unsigned int空间。
另外:unsigned char或者其他类型不必考虑。
三.何时位段会失效
例如:
struct bits
{
unsigned int f1:1;
int word;
unsigned int f3:1;
};
按照内存对齐的规则,位段声明会无效,上述sizeof(struct bits)为12!
相关文章推荐
- C++学习笔记(二) bool const 和 #define 结构体内存对齐
- 关于内存对齐的学习笔记
- C/C++学习笔记8:内存中数据对齐的问题总结
- 【D3D11游戏编程】学习笔记十三:内存对齐的一点思考
- (转)【D3D11游戏编程】学习笔记十三:内存对齐的一点思考
- C++学习笔记2--函数重载 复杂的数据 内存对齐 指针数组 结构与指针 传值传址传引用 联合枚举类型别名
- 学习笔记-C/C++-结构体与sizeof,内存对齐的题目怎么做
- 关于内存对齐的学习笔记
- 学习笔记-C/C++-结构体与sizeof,内存对齐的题目怎么做
- 操作系统的内存对齐机制学习笔记
- STL源码剖析之开篇与内存配置器--学习笔记
- iOS 学习笔记10 core Text 对齐方式
- 汇编学习笔记---3内存访问
- nginx 源码学习笔记(七)——内存分配相关源码分析
- 黑马视频学习笔记-进制与内存(一)
- 黑马视频学习笔记-进制与内存(三)- 位运算
- 编程学习笔记之java相关::内存回收原理
- 逆向工程核心原理学习笔记(六):实战开辟新内存区域写入缓冲区跳转修改字符串
- c++学习笔记 内存四区 函数调用模型 指针强化
- [置顶] [汇编语言学习笔记][第三章寄存器(内存访问)]