精华内容
下载资源
问答
  • C语言结构体内存对齐

    2020-05-12 10:09:53
    C语言结构体内存对齐 结构体是C语言常用的数据结构,它也是C语言支持的唯一一种聚合类型。在编译器为某个结构体分配的时候,原来相邻的的成员的内存却未必是相邻的。这是怎么回事呢?请往下看。 观察一下下面的...

    C语言结构体内存对齐

    结构体是C语言常用的数据结构,它也是C语言支持的唯一一种聚合类型。在编译器为某个结构体分配的时候,原来相邻的的成员的内存却未必是相邻的。这是怎么回事呢?请往下看。
    观察一下下面的结构体:

    struct {
        char am1;
        short am2;
        int am3;
        short am4;
        int am5;
    }s1;
    

    很明显,该结构体有5个成员变量,那么结构体s1占用空间会是各个成员占用的空间之和吗?它们的内内存地址会是连续的吗?
    我们用一段程序看一下实际的情况:

    int main()
    {
     cout<<sizeof(int)<<" "<<sizeof(short)<<" "<<sizeof(char)<<endl;
     cout<<"sizeof(s1)£º"<<sizeof(s1)<<endl;
     cout << "&(s1.am1)"<<(uint32_t)&(s1.am1)<<" &s1.am2"<<(uint32_t)&s1.am2<<" &s1.am3 "<<(uint32_t)&s1.am3<<" &s1.am4"<<(uint32_t)&s1.am4<<" &s1.am5"<<(uint32_t)&s1.am5 << endl;
     return 0;
    }
    

    上面的代码很简单,就是看一下编译器认为结构体s1应该占用的空间是多大。好了不多说了,来看一下运行结果。
    下面是运行结果:
    4 2 1
    sizeof(s1):16
    &(s1.am1):5005324 &s1.am2:5005326 &s1.am3:5005328 &s1.am4:5005332 &s1.am5:5005336

    Process returned 0 (0x0) execution time : 0.829 s
    Press any key to continue.
    结构体s1占用的空间是16字节,明显不是各个成员的占用大小之和。
    这是怎么回事呢?
    其实是编译器在为该结构分配内存的时候,会尽量为每个成员分配在为4的整数倍的地址处 。可以想象为编译器每次取出4的连续字节的内存来摆放结构体成员,在上面的例子中,第一次取出的4字节可以储存am1, am2,然后空一个字节。再取4字节摆放后面的am3;再取4字节摆放short类型的am4,虽然后面还空两个字节,但是由于寻址的原因这两个字节已经不能用了,最后就是再取4字节储存int 类型的am5了。
    从上面的运行结果也可以看出,am2的地址与am3的地址相差2,而不是连续的。

    展开全文
  • 参考博文:C语言结构体内存对齐问题

    在这里插入图片描述
    参考博文:C语言结构体内存对齐问题

    成员对齐:
      以4字节对齐为例,如果自身类型小于4字节,则该成员的首地址是自身类型大小的整数倍;如果自身类型大于等于4字节,则该成员的首地址是4的整数倍。若内嵌结构体,则内嵌结构体的首地址也要对齐,只不过自身类型大小用内嵌结构体的最大成员类型大小来表示。数组可以拆开看做n个数组元素,不用整体看作一个类型。

    最后结构体总体补齐:
      以4字节对齐为例,如果结构体中最大成员类型小于4字节,则大小补齐为结构体中最大成员类型大小的整数倍;如果大于等于4字节,则大小补齐为4的整数倍。内嵌结构体也要补齐。
    参考博文:结构体内存对齐是什么鬼?

    展开全文
  • struct Node { int data; struct Node* next; }
  • C语言结构体内存对齐规律自我总结-- 如果有其他学习者已有一定理解,但是对某些地方还是有些疑惑,或许可以看懂我所写---主要为了自己总结复习--如有错误方便再改如果有其他学习者已有一定理解,但是对某些地方还是有些...

    C语言结构体内存对齐规律自我总结-- 如果有其他学习者已有一定理解,但是对某些地方还是有些疑惑,或许可以看懂我所写---主要为了自己总结复习--如有错误方便再改

    如果有其他学习者已有一定理解,但是对某些地方还是有些疑惑,或许可以看懂我所写—主要为了自己总结复习–如有错误方便再改)

    前要知识:

    CPU一次性能读取数据的二进制位数称为字长,一个字节=8位。

    那么32位处理器可以一次性最大处理4个字节的数据量。

    我们这里讨论的也是在32位计算机中,明白后可以按规律推广至64位计算机。

    那么在结构体中就需要注意,

    如果结构体类型中包含有某个结构体成员,它的类型所占字节数是等于4的,例如4字节的整型

    那么必须保证cpu一次就能把这四个字节全部读取。即读取的时候在整型的起始地址的边界开始读取,就可以一次性确保读取4个字节成功。

    设想如果,并不是在整型的边界读取数据的话, 那么它将会被分二次读取,才能读取完整这个整型所包含的所有数据。 这时候cpu还需额外的操作将分二次读取的数据整合在一起,降低了系统性能。

    切入正题:(32位计算机中)

    首先: 找到所在结构体所有成员当中----所占字节数最大的那个类型的成员.

    例:如果最大类型成员是int(4字节) 的情况

    那么需要保证永远可以在int内存起始地址边界位置读取数据

    例:如果最大类型成员是int 的情况

    struct temp

    {

    char a;

    char b;

    int c;

    };

    此为内存图示, [a][b][x][x][c][c][c][c] 共占8字节

    [x]代表内存补位; 补位以达到,cpu读取时,可以通过一次读取, 读取一个整型的所有数据.

    例:如果最大类型成员是short(2字节) 的情况

    那么需要保证永远可以在short内存起始地址边界位置读取数据

    struct temp

    {

    char a;

    short b;

    char c;

    };

    此为内存图示, [a][x][b][b][c][x] 共占6字节

    对于结构体中最大成员类型所占是2个字节的short情况下

    需注意, 对于32位计算机不是说我每次一定要读满4个字节, 是代表一次读取时可以小于等于4个字节数据. 但是不能超过4个字节的数据.

    short 最大类型情况下, 那么以每次读取2个字节来判断结构体内存所占字节的标准, 也就是通过补位达到

    cpu读取时,可以通过一次读取, 读取一个short的所有数据.

    总结: 以结构体成员类型所占字节数最大的那个成员为判别标准, 使 cpu读取时,总是可以通过一次读取, 就读取一个该类型的所有数据.

    展开全文
  • C语言结构体内存对齐规律自我总结-- 如果有其他学习者已有一定理解,但是对某些地方还是有些疑惑,或许可以看懂我所写---主要为了自己总结复习--如有错误方便再改 如果有其他学习者已有一定理解,但是对某些地方还是...

    C语言结构体内存对齐规律自我总结-- 如果有其他学习者已有一定理解,但是对某些地方还是有些疑惑,或许可以看懂我所写---主要为了自己总结复习--如有错误方便再改


    如果有其他学习者已有一定理解,但是对某些地方还是有些疑惑,或许可以看懂我所写—主要为了自己总结复习–如有错误方便再改)
    前要知识:
    CPU一次性能读取数据的二进制位数称为字长,一个字节=8位。
    那么32位处理器可以一次性最大处理4个字节的数据量。
    我们这里讨论的也是在32位计算机中,明白后可以按规律推广至64位计算机。

    那么在结构体中就需要注意,
    如果结构体类型中包含有某个结构体成员,它的类型所占字节数是等于4的,例如4字节的整型
    那么必须保证cpu一次就能把这四个字节全部读取。即读取的时候在整型的起始地址的边界开始读取,就可以一次性确保读取4个字节成功。

    设想如果,并不是在整型的边界读取数据的话, 那么它将会被分二次读取,才能读取完整这个整型所包含的所有数据。 这时候cpu还需额外的操作将分二次读取的数据整合在一起,降低了系统性能。

    切入正题:(32位计算机中)

    首先: 找到所在结构体所有成员当中----所占字节数最大的那个类型的成员.
    
    例:如果最大类型成员是int(4字节) 的情况
    那么需要保证永远可以在int内存起始地址边界位置读取数据
    例:如果最大类型成员是int 的情况
    struct temp
    {
    char a;
    char b;
    int c;
    };                      
    此为内存图示,  [a][b][x][x][c][c][c][c]    共占8字节           
     [x]代表内存补位;  补位以达到,cpu读取时,可以通过一次读取, 读取一个整型的所有数据.
    
    例:如果最大类型成员是short(2字节) 的情况
    那么需要保证永远可以在short内存起始地址边界位置读取数据
    struct temp
    {
    char a;
    short b;
    char c;
    };                      
    此为内存图示,  [a][x][b][b][c][x]            共占6字节
    对于结构体中最大成员类型所占是2个字节的short情况下
    需注意, 对于32位计算机不是说我每次一定要读满4个字节, 是代表一次读取时可以小于等于4个字节数据. 但是不能超过4个字节的数据.
    short 最大类型情况下, 那么以每次读取2个字节来判断结构体内存所占字节的标准, 也就是通过补位达到
    cpu读取时,可以通过一次读取, 读取一个short的所有数据.
    

    总结: 以结构体成员类型所占字节数最大的那个成员为判别标准, 使 cpu读取时,总是可以通过一次读取, 就读取一个该类型的所有数据.

    展开全文
  • C语言结构体对齐问题,是面试必备问题。 本文,除了用图解的方式讲清楚结构体知识点外,还将为你解答以下问题: 为什么会有结构体内存对齐? 结构体怎么对齐? 学习结构体对齐有什么用? 结构体...
  • C语言结构体对齐问题,是面试必备问题。 本文,除了用图解的方式讲清楚结构体知识点外,还将为你解答以下问题: 为什么会有结构体内存对齐? 结构体怎么对齐? 学习结构体对齐有什么用? 结构体...
  •   在计算结构体类型变量的大小时,就涉及到了内存对齐问题。 1. 结构体内存对齐规则   对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值   vs中的默认值为8; Linux中的默认值为4; 原则1:数据成员...
  • C语言结构体对齐也是老生常谈的话题了。基本上是面试题的必考题。内容虽然很基础,但一不小心就会弄错。写出一个struct,然后sizeof,你会不会经常对结果感到奇怪?sizeof的结果往往都比你声明的变量总长度要大,这...
  • c语言结构体使用是非常广泛的,但是结构体有一个问题,就是如果开头的字段属性是字符类型(char),紧跟着的是其他类型,比如整型、长整型、双精度、浮点型,这时候结构体的大小会发生改变,下面给出一个示例: ...
  • 关于结构体内存对齐(在没有#pragma pack宏的情况下) :  •原则1   数据成员对齐规则:结构(struct或联合union)的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员...
  • 最近找工作,被笔试给卡死了,很多基础都忘了,今天花了半天缕了下结构体内存对齐,整理下自己的心得,有哪里写错请指出。 我们直接例子说明: typedef struct TEST{ int a; char b[2]; double c; short d; double e...
  • 许多计算机系统对基本类型数据在内存中存放的位置有限制,它们会要求这些数据的首地址的值是某个数k(通常它为4或8)的倍数,这就是所谓的内存对齐,而这个k则被称为该数据类型的对齐模数(alignment modulus)。...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 19,568
精华内容 7,827
关键字:

c语言结构体内存对齐

c语言 订阅