-
结构体对齐
2021-01-25 17:27:58C程序结构体对齐 关于结构体对齐我把我的理解写下来; 结构体对齐的步骤: 1,结构体各个成员对齐; 2,结构体圆整 首先要了解几个概念: 1, 指定对齐值: 指定对齐值是由宏#pragma pack (N)指定的值,里面的N必须...C程序结构体对齐
关于结构体对齐我把我的理解写下来;
结构体对齐的步骤:1,结构体各个成员对齐; 2,结构体圆整
首先要了解几个概念:
1, 指定对齐值: 指定对齐值是由宏#pragma pack (N)指定的值,里面的N必须是2的幂次方,如1,2,4,8,16等。如果没有通过#pragma pack宏那么在32位的Linux主机上默认指定对齐值为4,64位的Linux主机上默认指定对齐值为8,ARM CPU默认指定对齐值为8;
在计算机内存中,结构体变量的存储通常是按字长对齐的。
例:
32位系统中,变量就按照4字节对齐;
64位系统中,变量就按照8字节对齐;4字节对齐和8字节对齐分别指的是他们的系统的默认对齐值;
2,
int , char , short,在计算机的内存存储中分别占4字节 ,1字节 , 2字节;
它所占内存大小的值叫自身对齐值,就是结构体变量里每个成员的自身大小;3,
有效对齐值: 结构体成员自身对齐时有效对齐值为自身对齐值与指定对齐值中较小的一个,
{自身对齐值,指定对齐值}取较小的一个4
结构体圆整时,为所有成员中自身对齐值最大的与指定对齐值较小的一个的整数倍
{所有成员中自身对齐值最大的一个,指定对齐值} 取较小的一个下面我们举一个例子: (32位系统默认对齐值为4)
typedef struct _st_struct1 typedef struct _st_struct2 { { char a; short b; short b; int c; int c; char a; } st_struct1; }st_struct2; sizeof(st_struct1) = ? sizeof(st_struct2) = ?
结构体的数据类型是相同的,只是顺序有所不同;
<1>左边编译结果是:8
<2>右边编译结果是:12
<1>的结果是这样得出来的:
结构体成员自身对齐时:
从图中看第一个数据成员放在offset为0的地方,其类型为char,占一个字节。
有效对齐值:b得存储要从自身对齐值与指定对齐值中的较小的一个
min(2,4),取2。short b 就应该从2开始,即它存放在2 . 3内;int c 的存储也是 min(4,4);取4。 即应该是4 , 5 ,6 ,7;
这样这组结构体数据就存储完成了;结构体圆整时:在结构体数据成员中自身的对齐值最大的那一个与指定对齐值较小的一个;min(4.4)
所以其整体对齐就是8<2>的结果是这样得出来的:
结构体成员自身对齐时:
从图中看第一个数据成员放在offset为0的地方,short b 类型;即存储在0 ,1 的位置
当我们存int c 的时候就应该考虑他的有效对齐值了,自身对齐值与指定对齐值中的较小的一个;
min(4,4) 这样 2, 3的位置就会被空出来。即存储在4 .5 .6. 7 的位置;
接着char a 就存储在8的位置,
在结构体圆整时,其字节数大小为min(4.4),取4。其意思就是虽然 char a 只占一个字节但是需要四个字节存储他,而他只占一个字节,所以结构体总体对齐时为12字节;宏#pragma pack (N)指定的值
#pragma pack(1):设置结构体的边界对齐为1个字节,其存储时连续的但是处理大数据效率偏低;#pragma pack(1) #pragma pack(2) typedef struct _st_struct3 typedef struct _st_struct4 { { char a; char a; short b; int c; int c; short b }st_struct3; }st_struct4;
<3>左边编译结果是:7
<4>右边编译结果是:8
<3>的结果是这样得出来的:
结构体成员自身对齐时:
从图中看第一个数据成员放在offset为0的地方,放 char a.
放置short b 时:
考虑有效对齐值:{自身对齐值,指定对齐值}取较小的一个;
min{2,1} 取 1;所以short b 的存储位置为 1, 2;
放置 int c 时:
有效对齐值:{自身对齐值,指定对齐值}取较小的一个;
min{4,1} 取 1;所以int a 的存储位置 3 ,4 ,5 ,6;
结构体圆整时:
{所有成员中自身对齐值最大的一个,指定对齐值} 取较小的一个
min{4,1} 取1 所以结构体总体对齐为7;
<4>的结果是这样得出来的:
结构体成员自身对齐时:
从图中看第一个数据成员放在offset为0的地方,放置char a ;
其位置为0 ;
放置 int c 时:
考虑有效对齐值:{自身对齐值,指定对齐值}取较小的一个;
min{4,2} 取 2;所以int c 的存储位置为 2 ,3 ,4 ,5;
放置 short b时:
考虑有效对齐值:{自身对齐值,指定对齐值}取较小的一个;
min{2,2} 取 2;所以 short b的存储位置为 6, 7;
结构体圆整时:
{所有成员中自身对齐值最大的一个,指定对齐值} 取较小的一个
min{4,2} 取2 ;所以结构体总体对齐为8;**注意:**在我们遇到这样的问题我们应该先弄清楚几个‘ 量 ’ 。什么是自身对齐值,什么是指定对齐值,什么是有效对齐值,什么是结构体圆整;
-
结构体 对齐
2015-02-27 15:14:40结构体对齐 其实就是省点内存 主要在面试中常考 主要就是 struct mystruct { int n; double d; char c; }; void main() { struct mystruct ms;//c语言要加上 struct C++ 不需要 printf("%d...结构体:
1.结构体对齐 其实就是省点内存 主要在面试中常考 主要就是
struct mystruct
{
int n;
double d;
char c;
};
void main()
{
struct mystruct ms;//c语言要加上 struct C++ 不需要printf("%d", sizeof(ms));
system("pause");
}输出是24 主要是看 站字节 最大的那个 double 是8个字节 所以 double 上面的 变量和 和 下面的变量和 必须是d 的倍数 函数 不占字节 d=(n+4) d=(c+7)
-
结构体对齐规则
2019-07-28 18:42:26结构体对齐结构体:
结构体(struct)是由一系列具有相同类型或不同类型的数据构成的集合。因为这一特性,方便了开发者在使用的过程中可以将需要的不同的数据类型放在一起,做成我们需要的数据类型,通过结构体封装一些属性来组成新的类型。在我们实现链表的时候也很好的体现了这一点
但是,结构体在使用的过程中需要格外的注意!!!
结构体的大小及对齐规则:
结构体的大小不是结构体体中数据简单的相加,因为我们主流的计算机使用的都是32bit字长的CPU,对这类型的CPU取4个字节的数要比取一个字节要高效、方便。这就是内存对齐的由来。
每个平台上的编译器都有自己的默认“对齐系数”(也叫对齐模数)。开发者也可以通过预编译命令#pragma pack(n),n=1,2,4,8,16来改变这一系数,n为指定的“对齐系数”。结构体对齐规则:
1、结构体(struct)的数据成员,第一个数据成员放在offset为0的位置,以后每个数据成员在对齐数的整数倍的位置。
对齐数=编译器默认的对齐数与该成员大小的较小值。
VS中默认对齐数为8,linux默认对齐数为4.
2、结构体总大小为最大对齐数(每个成员都有一个对齐数)的整数倍。
3、如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。struct A { int a; char b; double c; }; //sizeof(A)=16; struct B { char b; double c; int a; }; //sizeof(B)=24
struct A和struct B里面的数据除了顺序不同,里面的数据是一样的,但是编译之后发现它们的结构体长度是不一样的。所以数据的顺序不同结构体的对齐方式也不同,结构体的大小自然不同
struct A :a是4字节,b是1字节,不符合对齐规则,所以b自动补全3个字节刚好和a加起来是8字节完成对齐,c是8字节,所以加起来是16字节
struct B :b是一个字节,不符合对齐规则,不全7个字节完成对齐,c是8个字节,b是4个字节,不符合对齐规则,不全4个字节完成对齐,所以struct B的大小是24