详解linux下C语言结构体对齐(内存对齐问题)
来源:互联网 发布:mac桌面下方白条 编辑:程序博客网 时间:2024/05/20 03:42
详解C语言结构体对齐(内存对齐问题)
C语言结构体对齐也是老生常谈的话题了。内容虽然很基础,但一不小心就会弄错。我在刚开始接触的时候也会是很迷糊,通过编译器运行的结果总是和自己的不一样,使自己很苦恼。在网上查了很多的资料,但是说的都很迷糊,但是内存对齐是怎么回事呢?我将网上所说的东西和自己的了解总结一下,其实理解后是非常简单的东西。
首先说一下内存对齐的原则(测试基于linux fedora8)
原则1、数据成员对齐规则:结构(struct或联合union)的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小的整数倍开始(比如int在32位机为4字节,则要从4的整数倍地址开始存储)。
原则2、结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储。(struct a里存有struct b,b里有char,int,double等元素,那b应该从8的整数倍开始存储。)
原则3、收尾工作:结构体的总大小,也就是sizeof的结果,必须是其内部最大成员的整数倍,不足的要补齐。
这三个原则具体怎样理解呢?我们看下面几个例子,通过实例来加深理解。
例1:struct A
{
short a1;
short a2;
short a3;
};
struct B
{
long a1;
short a2;
};
sizeof(struct A) = 6; 这个很好理解,三个short都为2。
sizeof(struct B) = 8; 这个比是不是比预想的大2个字节?long为4,short为2,整个为8,因为原则3。(结构体的总大小,也就是sizeof的结果,必须是其内部最大成员的整数倍,不足的要补齐)
运行结果图如下:
例2:
struct A
{
int a;
char b;
short c;
};
struct B
{
char b;
int a;
short c;
};
sizeof(struct A) = 8; int为4,char为1,short为2,这里用到了原则1和原则3。
sizeof(struct B) = 12; 是否超出预想范围?char为1,int为4,short为2,怎么会是12?还是原则1和原则3。
大家可能一个规则会用,但是将原则结合起来就有点犯迷糊了,下面写一下内存的布局。 a b c
A的内存布局:1111, 1*, 11
0123, 45, 67
其中星号*表示填充的字节
那为什么5为1个*号呢?为什么不继续将c的数据填充呢?
这就是用到原则1的地方(第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小的整数倍开始),因为5不能被2(c的字节数,c为short为两个字节)整除,换句话说就是起始位置要从该成员大小的整数倍开始,即其起始位置要为2的倍数,就是原则1。c的后面没有补充,因为b和c正好占用4个字节,整个A占用空间为4的倍数,也就是最大成员int类型的倍数,所以不用补充。
B a c
B的内存布局:1***, 1111, 11**
0123, 4567, 89,10,11
B中,b是char为1,b后面补充了3个字节,因为a是int为4,根据原则1,起始位置要为4的倍数,所以b后面要补充3个字节。c后面补充两个字节,根据原则3,整个B占用空间要为4的倍数,c后面不补充,整个B的空间为10,不符,所以要补充2个字节。
运行结果如下图:
再看一个结构中含有结构成员的例子:
例3:struct A
{
int a;
double b;
float c;
};
struct B
{
char e[2];
int f;
double g;
short h;
struct A i;
};
sizeof(struct A) = 24; 这个比较好理解,int为4,double为8,float为4,总长为8的倍数,补齐,所以整个A为24。
A的布局为:
a b c
1111* * * *, 11111111, 1111 * * * *
sizeof(struct B) = 48; 看看B的内存布局。
e f g h
B的内存布局:11* *, 1111, 11111111, 11 * * * * * *,
i
1111* * * *, 11111111, 1111 * * * * i其实就是A的内存布局。i的起始位置要为24的倍数,所以h后面要补齐。把B的内存布局弄清楚,有关结构体的对齐方式基本就算掌握了。
- 详解linux下C语言结构体对齐(内存对齐问题)
- 解析C语言结构体对齐(内存对齐问题)
- 解析C语言结构体对齐(内存对齐问题)
- 解析C语言结构体对齐(内存对齐问题)
- 解析C语言结构体对齐(内存对齐问题)
- C语言结构体对齐问题详解
- C语言结构体对齐问题详解
- C语言结构体对齐问题详解
- C语言结构体对齐问题详解
- C语言结构体对齐问题详解
- C语言结构体对齐问题详解
- C语言结构体存储 内存对齐问题
- C语言结构体中内存对齐问题
- 【C语言】结构体中的内存对齐问题
- C语言中结构体的内存对齐问题
- C语言、C++内存对齐问题详解
- Linux下C语言的内存对齐
- C语言结构体对象内存对齐
- MFC对话框设置焦点
- java.uitil.Locale类
- C# 引用 表值函数 远程表值函数不可用
- cocos2d-x 3.3rc0 实现Win8菜单效果
- C#版三层实例——三大高手各显神通(实战篇2)
- 详解linux下C语言结构体对齐(内存对齐问题)
- Yahoo WEB前端优化34条原则
- coursera android版本中提取下载后的课件视频-非root手机
- 如何装多个tomcat
- UICollectionview控件学习
- Web应用的缓存设计模式
- 关于webqq再次浅谈
- 开发注意事项
- web开发中存在的安全问题及防范