精华内容
下载资源
问答
  • 先说结论:sizeof求得的结构体的大小并不一定等于各个数据成员的大小之和。...而结构体A和B使用sizeof的结果分别为16个字节和24个字节。可以看出结构体B所占的字节数并不等于其成员之和:sizeof(B) ≠ sizeo...

    先说结论:sizeof求得的结构体的大小并不一定等于各个数据成员的大小之和。

    struct 

    比如有如上两个结构体:A和B。都含有两个int型,一个double型数据成员,但成员的顺序不一样。

    3770b9a9db7558db81ceec5aadfe14b0.png

    如上图所示,int 和 double 分别为4个字节和8个字节。而结构体A和B使用sizeof的结果分别为16个字节和24个字节。

    可以看出结构体B所占的字节数并不等于其成员之和:

    sizeof(B) ≠ sizeof(int) + sizeof(double) + sizeof(int)

    之所以出现这样的结果,就是因为编译器要对结构体的数据成员在空间上进行字节对齐

    一、什么是字节对齐

    现代计算机中,内存空间是按照字节划分的,理论上可以从任意起始地址访问任意类型的变量。但在实际中,访问特定类型变量时经常在特定的内存地址,这就需要各种数据类型按照一定的规则在空间上排列,而不是一个接一个地顺序存放。这就是所说的字节对齐。

    字节对齐主要针对的就是结构体。

    二、为什么需要字节对齐

    字节对齐的一个原因是:各个硬件平台对某些特定类型的数据只能从某些特定地址开始存取。比如有些架构的CPU在访问一个没有进行对齐的变量的时候会发生错误,在这种架构下编程必须保证字节对齐。

    其他平台可能没有这种情况,但是最常见的是如果不按照适合其平台要求对数据存放进行对齐,则会在存取效率上带来损失。

    三、字节对齐的规则

    字节对齐的规则如下:

    1. 结构体的大小等于其最大成员的整数倍;
    2. 结构体成员的首地址相对于结构体首地址的偏移量是其类型大小的整数倍。比如double型成员的首地址相对于结构体首地址的偏移量应该是8的倍数;
    3. 满足前两条规则后,编译器会在结构体成员之后进行字节填充。

    基于上述三条规则,可以把结构体的首地址和每个成员的首地址打印出来看一下,如下图所示。

    c15ea28918f12e6f8a2b8ec1acc812da.png

    如上图所示,

    • 结构体sa和sb中,第一个成员x的首地址与结构体的地址相同,因为结构体不会在第一个数据成员之前进行字节填充;
    • 在结构体sa中,y的首地址相比x偏移了4个字节,z的首地址相比x偏移了8个字节,满足上述规则,结构体A所占的总空间为16个字节;
    • 而在结构sb中,x的首地址是0,占用4个字节;而y是double类型,占用8个字节,但x只占用了4个字节,为了满足规则2,需要在x后面填充4个字节,因此y的首地址为8;x和y总共占用了16个字节,z首地址又从0开始,而z是int类型,但为什么结构体B所占的字节不是16+4=20呢?这是因为规则1(结构体的大小等于其最大成员的整数倍),由于结构体最大成员是double类型,8个字节,因此还需要在z后面填充4个字节,即结构体总共占24个字节。

    从上面可以看出,虽然结构体A和B包含的成员相同,但因为顺序不同,就导致结构体B比A多占了50%的空间,当结构体的数量足够多时,B比A所多占的空间就非常客观了。

    因此,在设计结构体时,需要仔细安排各个成员的顺序。

    展开全文
  • C语言_结构体 _ 字节对齐 - 详解 文章目录C语言_结构体 _ 字节对齐 - 详解@[toc]0 . 说明1.结构体__字节对齐的背景(本质)2.结构体__字节对齐的处理方式总结3.`4字节对齐`__实例展示a.发生字节对齐b.改变书写顺序c....

    C语言_结构体 _ 字节对齐 - 详解

    0 . 说明

    ​ 看滴水逆向视频总结笔记

    ​ 编译器VC++6.0

    1.结构体__字节对齐的背景(本质)

    ​ 由于我们32位的计算机在处理数据时最喜欢4个字节4个字节的处理,这样效率最高,所以在堆栈中,是4个字节一排,方便计算机每次处理4个字节。

    本机宽度:4个字节

    ​ 但是结构体在堆栈中分配一个连续的空间,一般会不等宽(char型数据一个字节,int型数据4个字节)。

    设想一下:在堆栈的一排4个字节中,先为char分配一个空间,那int型数据占后面三个字节+下一排的一个字节。这样在堆栈分配空间时,的确是最省空间的,数据全挨在一起。

    这种情况下,计算机要想调用这个int型数据,就要用两个堆栈地址。但是计算器为了提高效率,为了给这个int型数据 在堆栈中分配一个完整连续且在同一排的4字节空间,那么int型数据就不会占用第一排char型数据剩下的3个字节,而占用下一排完整的4个字节。

    那这个char型数据在堆栈中占据的那一排空间就会空出3个字节,让一个char型数据占了4个字节,这就是字节对齐,这里是4字节对齐

    ​ 所以,字节对齐的本质就是:作为计算机本身,是想要空间还是要效率?显然在对于处理结构体这样特定的数据时,就会选择效率。

    2.结构体__字节对齐的处理方式总结

    ​ 结构体的一个成员先占领一个堆栈空间,如果在这一排中剩下字节如果不能满足下一个成员的大小,那么下一个成员就会在下一排堆栈空间存放数据。

    如果能满足下一个成员的大小的情况下,两者大小不到四的话,小的一方补齐字节,平均分配这一排堆栈4个字节。

    3.4字节对齐__实例展示

    ​ 这里就用vc的内存演示,因为内存和堆栈本质上是一致的。

    a.发生字节对齐

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-30UeEO3Y-1584276639074)(E:/Typora/image/1584269750322.png)]

    ​ 总共为其分配了0xc个空间,但这四个成员的总体宽度只有8个字节。

    ​ 第一个成员stu.a发生字节对齐,char型数据占了4个字节。

    ​ 第三个成员stu.c也发生字节对齐,char型数据占2个字节。

    b.改变书写顺序

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HlqqKLnz-1584276639075)(E:/Typora/image/1584270767426.png)]

    ​ 我们发现,同样成员的结构体,因为书写顺序不同,这里就这分配了8个内存空间,两排堆栈[ebp-8]、[ebp-4]正好满满当当存放着4个成员,并没有发生字节对齐

    c.体会

    ​ 学会了字节对齐的概率后,发现不同的书写也会造成不同的空间分配,为减少不必要的浪费,即有效率同时节省空间,我们在书写的时候,一定要考虑字节对齐,合理安排书写顺序。

    4.拓展

    ​ 以上将的字节对齐全是基于4字节对齐,除此之外还有1字节对齐2字节对齐8字节对齐16字节对齐

    字节对齐是向下兼容的,也就是说,会自动适配结构体成员的宽度大小,选择最大的作为字节对齐的模式,

    ​ 一般VC++6.0是默认8字节对齐,而我们上述写的结构体中,宽度最大的成员是int型数据4个字节,所以自动适配按照4字节对齐

    ​ 右键项目文件->setting->C/C+±>Code Generation->Stuct menber alignment

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yvTrjDlU-1584276639075)(E:/Typora/image/1584272673816.png)]

    ​ 默认是8字节,可以更改,但是不建议更改。

    5.8字节对齐实例展示

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zE9a41ha-1584276639076)(E:/Typora/image/1584274502508.png)]

    可以发现

    1. 8字节对齐的方式,在内存空间中都是8个字节为一个整体。

    2. 8字节对齐4字节对齐的基础上,以8个字节为整体。

    3. double型数据占8个字节,在内存中分别以两个4字节储存

    例如:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YggxVekB-1584276639076)(E:/Typora/image/1584275652584.png)]

    6.强制转换 个别结构体 字节对齐的方式

    #pragma pack(n)//n代表字节对齐的方式n = 1、2、4、8、16.
    struct student
    {
    	char a;
    	int b;
    };
    #pragma pack()
    

    如果有有什么不懂或是我那个地方写的不对、不好的话,欢迎大家留言指正

    展开全文
  • 20 字节对齐_哔哩哔哩 (゜-゜)つロ 干杯~-bilibili​www.bilibili.com这位大神的视频超级棒,看完绝对就会了,顺便可以用下面另一位高手的试题测试一下结构体 字节对齐的练习​www.jianshu.com我来自己总结一下:(也...

    f8f1d3d5e25f24a67a9fc7c3b4af9d5c.png

    最近在备战秋招,面经里很多次提到字节对齐,干脆整明白它!!!!

    20 字节对齐_哔哩哔哩 (゜-゜)つロ 干杯~-bilibiliwww.bilibili.com
    d97db0b5188fa908d722586762c344a3.png

    这位大神的视频超级棒,看完绝对就会了,顺便可以用下面另一位高手的试题测试一下

    结构体 字节对齐的练习www.jianshu.com
    c5f206c29fb463cca24fa9fd700dc20c.png

    我来自己总结一下:(也可以直接看最后的解题思路,但是看完的更好 )

    首先来看正常情况下的字节对齐(64位机器)

    char 

    其中a的起始地址若为0,则b的起始地址位4

    因为每个变量的地址的起始地址都是本类型大小的整数倍。

    然后来看结构体

    struct 

    此时

    变量对齐

    c1 大小为1,起始地址为0

    d 大小为4,起始地址为4(因为需要从本身整数倍的地址开始,不够的系统补足)

    c2 大小为1,起始地址为8(任何时候都是1的整数倍,可直接存放)

    c3 大小为1,起始地址为9(任何时候都是1的整数倍,可直接存放)

    337f1027db4b07c845d406182d8c27f5.png

    结构体整体对齐

    但是这还不算完,整个结构体还要进行字节对齐,对齐标准是本结构体内最大的变量类型大小的整数倍。

    本次的结构体最大为int类型,4

    到c3为9,不够,需要加2,得11(大小为12,为4的整数倍,因为从0开始)

    再来一个

    struct 

    c8bcef8994fb27eb8470bf019a7ad4a8.png

    如果有字节对齐控制pragma pack(len)

    pragma pack(2)可以控制对齐大小,为2,通过它来确定每个变量对齐及结构体整体对其的大小,取小值

    #pragma pack(2)
    

    261ddc473d81e92cf5ad4bcf00eb4f00.png

    结构体整体补齐,现在为8,是2的整数倍,不用补齐

    如果一个结构体A作为另一个结构体B的变量,则A作为变量的对齐标准standard为A的整体对齐大小struct_standard;

    struct 

    运行得 sizeof(S1)=40 sizeof(S3)=56

    S1的struct_standard为8

    S3中s1的作为变量的standard为S1的struct_standard为8

    S3的struct_standard的大小为

    max(c1.standard,s1.standard,c2.standard,c3.standard)=s1.standard=8

    但如果S3有字节对齐控制#paragma back(1)的话

    S3的struct_standard的大小为min(struct_standard,1)=1

    sizeof(S3)=43

    做题思路:(整体对齐标准struct_standard,变量对齐标准standard)

    1.先确定每个变量的standard

    如果变量是数据类型(int,char,double)那么

    变量.standard=sizeof(变量类型)

    若变量是结构体A

    变量.standard=结构体A.struct_standard

    2.再看整体的struct_standard

    struct_standard=max(变量1.standard,变量2.standard,.......)

    全部比较完之后,如果有字节对齐控制#paragma back(len)的话

    struct_standard=min(struct_standard,len)

    此时struct_standard确定

    3.再看每个变量的standard,补足整数倍

    变量.standard=min(变量.standard,struct_standard)

    4.最后结构体整体补足struct_standard的整数倍

    所有变量的地址大小确定完,根据整体为struct_standard的整数倍,确定整体大小

    展开全文
  • 结构体字节对齐

    2016-11-09 11:32:24
    1. 结构体的字节对齐: 在C语言里,结构体所占的内存是连续的,但是各个成员之间的地址不一定是连续的。所以就出现了"字节对齐". ...1) 结构体字节对齐  #include #include   struct Box
     1. 结构体的字节对齐:
    在C语言里,结构体所占的内存是连续的,但是各个成员之间的地址不一定是连续的。所以就出现了"字节对齐".
     
    结构体变量的大小,一定是其最大的数据类型的大小的整数倍,如果某个数据类型大小不够,就填充字节。
    结构体变量的地址,一定和其第一个成员的地址是相同的。
     
    1) 结构体字节对齐 
    #include <stdio.h>
    #include <string.h>
     
    struct Box
    {
    // 首先检查结构体成员里最大的数据类型是 double, 占8个字节,则
    int height; // 系统判断 int 可以和相邻的 char name[10] 共同填充字节
    char name[10]; // char name[10] 需要填充 到double 的倍数,但是可以和相邻的 int 一起累加,再填充4个字节,对齐 double 的2倍
    double width; // double 是所有成员里最大数据类型,满足double 的1倍
    char type; // char 会填充7个字节,对齐double 的1倍
    };
     
    int main(void)
    {
    struct Box box;
    box.height = 4; // 高度
    strcpy(box.name, "Dropbox"); // 名称
    box.width = 5.5; // 宽度
    box.type = 'C'; // 类型
     
    printf("box = %p\n", &box);
    printf("box.height = %p\n", &box.height);
    printf("box.name = %p\n", box.name);
    printf("box.width = %p\n", &box.width);
    printf("box.type = %p\n", &box.type);
     
    printf("box = %d\n", sizeof(box)); // 16 + 8 + 8 = 24
    return 0;
    }
     
     
     
    2) 初识链表
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
     
    struct Student
    {
    char *name; // 姓名
    int age; // 年龄
    struct Student *next;
    // next 是结构体成员,但是类型是 struct Student * 类型,用来指向某个 struct Student 的结构体变量的。
    // 结构体可以看做是一个自定义的数据类型,而且结构体可以嵌套,但是嵌套有条件:
    // 结构体只可以嵌套自身类型的结构体指针,但是绝对不能嵌套自身类型的结构体变量
    // 比如,不能嵌套 struct Student next; 这种
    };
     
    int main(void)
    {
    struct Student stu, *stup; // 定义了一个结构体变量 stu 和 一个结构体指针变量 stup
     
    stu.name = (char *)malloc(10 * sizeof(char)); // 给姓名申请了一个10个字节的堆空间
    strcpy(stu.name, "damao"); // 拷贝字符串 "damao" 给 stu.name (注意,不能直接赋值,要用拷贝)
    stu.age = 18; // 今年 18岁了
     
     
    stup = (struct Student *)malloc(1 * sizeof(struct Student)); // 给 stup 申请一个堆空间,用来保存两个指针(name,next)和一个int
    stup->name = (char *)malloc(10 * sizeof(char)); // 给 stup->name 申请一个堆空间,保存字符串
    strcpy(stup->name, "ermao"); // 拷贝字符串
    stup->age = 16; // 今年 16岁了
     
    stu.next = stup; // stu的成员next 指向了 结构体变量 stup 的首地址,链表诞生
    stup->next = NULL; // stup的成员 next 指向 NULL, 保证安全。
     
    free(stup->name); // 最后申请的堆 最先释放
    free(stup); // 继续释放
    free(stu.name); // 最先申请的堆 最后释放
     
    return 0; // 程序正常结束
    }
    展开全文
  • C语言结构体字节对齐原则
  • 这就牵扯到结构体字节对齐的概念。 (什么叫字节对齐结构体是一种构造数据类型,里面可以有不同的数据类型的成员,在这些数据成员中,不同的数据类型所占的内存空间是不同的,那么这些成员是...
  • 既然提到了struct那么肯定就避免不了结构体结构体的内存对齐1. 什么是结构体结构体是一系列类型数据的集合这些数据可能描述了一个物体。 2. 什么时候会用到结构体1. 当内置类型无法满足用户需求的时候,...
  • 下面直接来看例子吧:测试环境为32位的系统以下结构体分别占多少字节:struct A { char a; char b; char c; };sizeof(A) = 3; //因为a、b、c按照1个字节... 按照4个字节对齐: a占4字节 b占一个字节 c占2个字节 有1
  • 结构体-字节对齐原则

    2020-03-16 21:02:30
    字节对齐的细节和具体的编译器有关,但一般而言,满足三个准则: 结构体变量的首地址能够被其最宽基本类型成员的大小所整除; 结构体每个成员相对于结构体首地址的偏移量都是成员大小的整数倍,如有需要编译器会在...
  • 结构体自身字节对齐

    2014-09-08 11:25:44
    在用sizeof运算符求算某结构体所占空间时,并不是简单地将结构体中所有元素各自占的空间相加,这里涉及到内存字节对齐的问题。从理论上讲,对于任何变量的访问都可以从任何地址开始访问,但是事实上不是如此,实际上...
  • 文章目录结构体字节对齐问题遵循的规则:典型例子:需要内存对齐的原因: 结构体字节对齐问题 遵循的规则: 某数据类型的变量存放的地址需要按有效对齐字节剩下的字节数可以被该数据类型所占字节数整除,char...
  • 1、理想情况下,都是按照自身所占字节数进行对齐,此时结构体此时所占空间最大。 2、所占字节小的变量所占空间会被下一个所占字节大的变量影响,具体影响有如下几种。 小变量所占空间和大变量所占空间相同 前面...
  • 结构体字节对齐

    2018-05-08 23:15:02
    对于大多数像我这样的c语言初学者来说,结构体无疑是一个让人头疼的地方,今天我就自己的理解,写一篇有关结构体基础知识的文章。在我们想要写一个结构体时,大多数同学可能都会说“定义”结构体,其实这样的说法不...
  • 对于结构体的空间对齐规则,我刚开始的理解是...1.系统在为结构体变量分配空间的时候,先会判断结构体中那个类型的成员所占的空间大小最大并以那个字节作为空间对齐字节。(若表述难理解,可参考以下例子) 2.每个
  • 结构体字节对齐在用sizeof运算符求算某结构体所占空间时,并不是简单地将结构体中所有元素各自占的空间相加,这里涉及到内存字节对齐的问题。从理论上讲,对于任何 变量的访问都可以从任何地址开始访问,但是事实上...
  • 要求数据内存的起始地址的值是某个数k的倍数,这就是所谓的内存对齐,本文就来深入剖析C++中的struct结构体字节对齐,需要的朋友可以参考下 1.什么是字节对齐,为什么要对齐? 现代计算机中内存空间都是按照byte划分...
  • 结构体结构体的作用数组:具有相同类型的数据的集合结构体:存储不同类型的数据项 单一的数据类型无法满足特定的需求,数据类型的...定义结构体后再定义变量//例1: 在定义结构体的同时定义变量//例2: 引用结构体变...
  • 结构体在内存中所占的大小,就是其字段所占的大小,但是,它的大小并不是所有字段大小相加,而是存在一个对齐的规则,在默认的对齐规则中,基本类型字段是按照自身大小对齐的,如byte是按1字节对齐。struct A { ...
  • 结构体字节对齐方式

    千次阅读 2010-01-14 09:27:00
    结构体字节对齐方式#includestruct a{ char no[10]; int p; long int pp; unsigned int ppp; char x; float y; double h;} xy;void main(){ printf("struct a: %d /n",
  • 结构体字节对齐 在用sizeof运算符求算某结构体所占空间时,并不是简单地将结构体中所有元素各自占的空间相加,这里涉及到内存字节对齐的问题。从理论上讲,对于任何 变量的访问都可以从任何地址开始访问,但是事实...
  • 结构体成员字节对齐

    2012-03-15 12:16:27
    为什么需要字节对齐?计算机组成原理教导我们这样有助于加快计算机的取数速度,否则就得多花指令周期了。为此,编译器默认会对结构体进行处理(实际上其它地方的数据变量也是如此),让宽度为2的基本数据类型(short...
  • 结构体字节对齐在用sizeof运算符求算某结构体所占空间时,并不是简单地将结构体中所有元素各自占的空间相加,这里涉及到内存字节对齐的问题。从理论上讲,对于任何 变量的访问都可以从任何地址开始访问,但是事实上...
  • 结构体是C语言中一种类似于类的变量; 关键字为struct; 定义方式: struct student { ...设置字节对齐,使用#pragma pack() ...#pragma pack(1) // 让编译器做1字节对齐 struct student { ...
  • C++中结构体字节对齐问题
  • 结构体4字节对齐规则的详解

    千次阅读 2013-04-17 17:08:57
    C++中结构体变量的存储为什么有个4字节对齐的规则,这里是假设32位机器上,CPU在读取内存数据的时候4字节对齐会取得更快的速度;这是因为:1字节8位,4字节正好32位,而32位机器的寄存器,地址什么的都是32位的,正好...
  • 64位驱动开发中结构体8字节对齐

    千次阅读 2017-10-20 14:45:19
    但是在判断句柄类型为28,即文件句柄的时候发生了严重的错误,导致很多进程中的打开的句柄无法获取,找了很多原因,最后发现是因为驱动在定义结构体的时候按1字节对齐,导致发生了错误。驱动中的结构在64位WIN7下...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 38,341
精华内容 15,336
关键字:

结构体1字节对齐