字节对齐 订阅
字节(Byte)是计算机信息技术用于计量存储容量和传输容量的一种计量单位,一个字节等于8位二进制数,在UTF-8编码中,一个英文字符等于一个字节。字节按照一定规则在空间上排列就是字节对齐。 展开全文
字节(Byte)是计算机信息技术用于计量存储容量和传输容量的一种计量单位,一个字节等于8位二进制数,在UTF-8编码中,一个英文字符等于一个字节。字节按照一定规则在空间上排列就是字节对齐。
信息
外文名
Byte aligned
拼    音
zi jie dui qi
相关领域
计算机信息技术
释    义
字节按照一定规则在空间上排列
中文名
字节对齐
性    质
一种计量单位
字节对齐解释
现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特 定的内存地址访问,这就需要各种类型数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放,这就是对齐。
收起全文
精华内容
下载资源
问答
  • 2021-03-04 06:34:07

    字节对齐

    为什么字节对齐?

    一个字或双字操作数跨越了4字节边界,或者一个四字操作数跨越了8字节边界,被认为是未对齐的,从而需要两次总线周期来访问内存。一个字起始地址是奇数但却没有跨越字边界被认为是对齐的,能够在一个总线周期中被访问

    为了提高CPU访问内存中的数据的效率在给每个数据变量分配内存空间时,需考虑地址对齐

    (1)自然对齐:在给数据分配内存空间时,如果各成员数据的空间的起始地址能够被数据的长度整除,结构的总大小是最大sizeof(类型)的整数倍

    typedef struct _a

    {

    char c1;

    long i;

    char c2;

    double f;

    }a;

    typedef struct _b

    {

    char c1;

    char c2;

    long i;

    double f;

    }b;

    结构体a的长度为24,c1一个字节,i四个字节,为了对齐,C1要补齐3个字节,C2一个字节,f八个字节,为了对齐,C2要补齐3个字节,这里一共20个字节,因为总长度要是最大sizeof(double)的倍数,所以要为24个字节

    结构体b的长度为16,c1一个字节,C2一个字节,补齐2字节,i四个字节,f八个字节,一共为16个字节,也是8的倍数

    (2)适当对齐:在给数据分配内存空间时,如果数据的空间的起始地址能被数据的M值整除,结构的总大小是M值的整数倍

    对于不同的数据都存在一个M值

    当数据的长度

    当数据的长度>机器字长M=机器字长

    基本数据:长度对齐

    数组:     以元素的M值对齐

    指针:     以4字节对齐

    联合体:   成员中最大的M值对齐

    结构体:   成员中最大的M值(成员排序不同,所占内存大小不一样)

    struct A{

    char x;

    int y;

    short z;

    }st1;

    struct B{

    char x;

    short z;

    int y;

    }st2;

    结构体A总长度为12,首先看M值,最大的是y,四个字节,未超过机器字节,所以M为4,x一个字节,补齐3字节,y四个字节,z两个字节,补齐2字节,一共12字节,是M的倍数

    结构体B总长度为8,M值也是为4,x一个字节,z两个个字节,补齐一个字节,y四个字节,一共8个字节,是M的倍数

    从上面可以看到,结构体成员是一样的,但是顺序不一样,导致了占用的空间不一样,所以我们在定义结构体成员时,最好是按字节长度从小到大定义,可以节省空间

    (3)栈上对齐:函数内的变量一般都是存在栈上的,x86平台是四字节对齐,x64平台是16字节对齐

    Void test(void)

    {

    char c =0;

    int a = 4;

    char str[10]= "hello";

    float f = 2.0f;

    f = a+c;

    }

    占用空间是24字节,c一个字节,补齐3字节,a四个字节,str占10个字节,补齐2字节,f四个字节,一共24字节

    更多相关内容
  • 本文主要讲了什么是字节对齐,为什么要对齐,已经应该注意的一些问题,下面一起来看看
  •  我们先看看sizeof的定义——sizeof的结果等于对象或者类型所占的内存字节数,好吧,那让我们来看看S1的内存分配情况  S1 s1 = { 'a', 0xFFFFFFFF };  定义上面的变量后,加上断点,运行程序,观察s1所在的...
  • 本文介绍了字节对齐的原因、作用以及什么时候需要对齐。
  • 要求数据内存的起始地址的值是某个数k的倍数,这就是所谓的内存对齐,本文就来深入剖析C++中的struct结构体字节对齐,需要的朋友可以参考下
  • 什么是字节对齐,为什么要对齐 现代计算机中内存空间都是按照BYTE划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特定的内存地址访问,这就需要各种...
  • 本篇文章是对C++内存中字节对齐的问题进行了详细的分析与总结。需要的朋友参考下
  • VS C++字节对齐方式

    2020-12-18 23:56:48
    VS C++字节对齐方式
  • 本文介绍了ucos中变量字节对其的原因。
  • 什么是字节对齐,为什么要对齐?  现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特 定的内存地址访问,这就需要...
  • 讲讲字节对齐吧. /******************************分割线 如果体系结构是不对齐的,A中的成员将会一个挨一个存储,从而sizeof(a)为11。显然对齐更浪费了空间。那么为什么要使用对齐呢?体系结构的对齐和不对齐,是在...
  • 关于C语言中的结构体字节对齐问题,在《C与指针》一书中提到,但是似乎没有说清楚,还是我理解不完全?所以,根据书上和网上资料,总结一些关于C语言中的结构体字节对齐的知识。这里的讨论和代码,都在VS2010下,GCC...
  • 在这里就分享两条开发中曾经忽略的问题:1、Union(联合体)的字节对齐先...调试一下结构体的内存布局,发现,union自身增加了2个字节的填充,用来保持Union本身的4字节对齐。即union在内存中变成:union{double dTest
  • 写出一个struct,然后sizeof,你会不会经常对结果感到奇怪?sizeof的结果往往都比你声明的变量总长度要大,这是怎么回事呢?讲讲字节对齐吧.
  • 最近在调试过程中,一直发现结构体中数据错位现象,但是仿真器查看,又都正确..无意中数了数缓存前面的变量,是奇数字节.改称偶数字节后,一切正常..
  • ARM重定向代码字节对齐问题的解析。
  • C语言字节对齐4

    2021-05-19 07:53:56
    字节对齐类型的字节对齐规则我们可以使用“__packed”、“__attribute__((packed))”、“#pragma”等方式控制结构体的字节对齐,这些结构体的内部结构在定义时就已经确定了,当它们被包含在其它结构体内部时它们被...

    非字节对齐类型的字节对齐规则

    我们可以使用“__packed”、“__attribute__((packed))”、“#pragma”等方式控制结构体的字节对齐,这些结构体的内部结构在定义时就已经确定了,当它们被包含在其它结构体内部时它们被当做一个整体来看待,其内部结构不受外面字节对齐控制方式的影响,但它们的对齐方式却受外面结构体的对齐方式控制,来看下面的例子:

    #pragmapack(2)

    typedef struct example26_1

    {

    char a;

    int b;

    char c;

    }EXAMPLE26_1;

    #pragma pack(1)

    typedef struct example26_2

    {

    char a;

    EXAMPLE26_1 b;

    int c;

    }EXAMPLE26_2;

    #pragma pack()

    typedef struct example26_3

    {

    char a;

    EXAMPLE26_1 b;

    int c;

    }EXAMPLE26_3;

    EXAMPLE26_1的内存分布示意图如下:

    a

    b

    b

    b

    b

    c

    EXAMPLE26_1的数据如下:

    sizeof(EXAMPLE26_1)

    8

    OFFSET(EXAMPLE26_1, a)

    0

    OFFSET(EXAMPLE26_1, b)

    2

    OFFSET(EXAMPLE26_1, c)

    6

    EXAMPLE26_1结构体按照2字节对齐,这个没什么好说的了,前面已经介绍过。

    EXAMPLE26_2结构体按照1字节对齐,它里面的a、b、c都按照1字节对齐。其中b是一个按照2字节对齐的EXAMPLE26_1结构体,内部有2个填充的1字节,当b出现在要求1字节对齐的EXAMPLE26_2结构体中,b需要按照1字节对齐,注意,但其内部结构不能发生变化,那2个填充的1字节仍保留。

    来看内存分布示意图:

    a

    b.a

    b.b

    b.b

    b.b

    b.b

    b.c

    c

    c

    c

    c

    EXAMPLE26_2的数据如下:

    sizeof(EXAMPLE26_2)

    13

    OFFSET(EXAMPLE26_2, a)

    0

    OFFSET(EXAMPLE26_2, b.a)

    1

    OFFSET(EXAMPLE26_2, b.b)

    3

    OFFSET(EXAMPLE26_2, b.c)

    7

    OFFSET(EXAMPLE26_2, c)

    9

    EXAMPLE26_3结构体按照4字节对齐,EXAMPLE26_2结构体是按照2字节对齐的,因此b.a虽然是char型变量,但也需要对齐到2字节,在a之后需要保留一个填充字节。b.a与b.b之间保留的一个字节不是因为b.b需要对齐到4字节而保留的,而是EXAMPLE26_2结构体在定义时按2字节对齐而保留的。

    来看内存分布示意图:

    a

    b.a

    b.b

    b.b

    b.b

    b.b

    b.c

    c

    c

    c

    c

    EXAMPLE26_3的数据如下:

    sizeof(EXAMPLE26_3)

    16

    OFFSET(EXAMPLE26_3, a)

    0

    OFFSET(EXAMPLE26_3, b.a)

    2

    OFFSET(EXAMPLE26_3, b.b)

    4

    OFFSET(EXAMPLE26_3, b.c)

    8

    OFFSET(EXAMPLE26_3, c)

    12

    总结一下字节对齐的规则:

    1.确定结构体中每种结构对齐的字节数,找出其中最大的字节对齐数N,求得结构体对齐规则的对齐数M,取M与N中的最小值min(M, N)作为该结构体的字节对齐数。结构体中每种结构的对齐数为默认对齐数P与min(M, N)的最小值min(P, min(M, N))。若结构体中包含子结构体,则先确定子结构的字节对齐数。

    2.结构体中每个结构的开始都需要对齐到min(P, min(M, N))字节,若无法对齐前面会有保留的填充字节。结构体中每个结构的结束都需要对齐到下个对齐字节min(P, min(M, N)),若无法对齐则在后面填充空闲字节。

    3.结构体作为一个整体存在,对于包含它的结构体来说它是一个黑盒。其内部按自己的对齐方式对齐,被包含时整体按照父结构对齐。

    下面我们使用上面的规则来分析一下结构体EXAMPLE27_3的对齐方式。

    #pragmapack(1)

    typedef struct example27_1

    {

    char a;

    short b;

    }EXAMPLE27_1;

    #pragma pack(2)

    typedef struct example27_2

    {

    EXAMPLE27_1 a;

    int b;

    char c;

    }EXAMPLE27_2;

    #pragma pack()

    typedef struct example27_3

    {

    char a;

    EXAMPLE27_2 b;

    }EXAMPLE27_3;

    结构体EXAMPLE27_3中包含结构体EXAMPLE27_2,结构体EXAMPLE27_2中包含结构体EXAMPLE27_1,需要先确定结构体EXAMPLE27_1的对齐字节数。

    结构体EXAMPLE27_1里面都是基本类型的变量,char型变量a对齐到1字节,short型变量b对齐到2字节,这其中最大的是2字节对齐。结构体EXAMPLE27_1使用的对齐规则是1个字节对齐,因此结构体1的字节对齐数是min(2, 1),是1字节对齐。因此,变量a对齐到min(1 ,1)=1字节,变量b对齐到min(2, 1)=1字节。

    它的内存分布示意图如下:

    a

    b

    b

    EXAMPLE27_1的数据如下:

    sizeof(EXAMPLE27_1)

    3

    OFFSET(EXAMPLE27_1, a)

    0

    OFFSET(EXAMPLE27_1, b)

    1

    结构体EXAMPLE27_2中包含了EXAMPLE27_1型的变量a、int型的变量b和char型的变量c,EXAMPLE27_1型是1字节对齐,int型是4字节对齐,char型是1字节对齐,这其中最大的是4字节对齐。结构体EXAMPLE27_2型的字节对齐规则是2字节对齐,因此结构体EXAMPLE27_2的字节对齐数是min(2, 4),是2字节对齐。因此,变量a对齐到min(1, 2)=1字节,变量b对齐到min(4, 2)=2字节,变量c对齐到min(2, 2)=2字节。变量a占用3个字节,因此在变量a之后需要有一个保留字节,变量b才能对齐到2字节,变量c之后需要保留1个空闲字节才能对齐到下一个2字节。

    它的内存分布示意图如下:

    a.a

    a.b

    a.b

    b

    b

    b

    b

    c

    EXAMPLE27_2的数据如下:

    sizeof(EXAMPLE27_2)

    10

    OFFSET(EXAMPLE27_2, a.a)

    0

    OFFSET(EXAMPLE27_2, a.b)

    1

    OFFSET(EXAMPLE27_2, b)

    4

    OFFSET(EXAMPLE27_2, c)

    8

    结构体EXAMPLE27_3中包含了char型的变量a和EXAMPLE27_2型的变量b,char型是1字节对齐,EXAMPLE27_2型是2字节对齐,这其中最大的是2字节对齐。结构体EXAMPLE27_3型的字节对齐规则是4字节对齐,因此结构体EXAMPLE27_3的字节对齐数是min(4, 2),是2字节对齐。因此变量a对齐到min(1, 2)=1字节,变量b对齐到min(2, 4)=2字节。变量a占用了1个字节,因此变量a之后需要哟袷保留字节,变量b才能对齐到2字节。

    它的内存分布示意图如下:

    a

    b.a.a

    b.a.b

    b.a.b

    b.b

    b.b

    b.b

    b.b

    b.c

    EXAMPLE27_3的数据如下:

    sizeof(EXAMPLE27_3)

    12

    OFFSET(EXAMPLE27_3, a)

    0

    OFFSET(EXAMPLE27_3, b.a.a)

    2

    OFFSET(EXAMPLE27_3, b.a.b)

    3

    OFFSET(EXAMPLE27_3, b.b)

    6

    OFFSET(EXAMPLE27_3, b.c)

    10

    非字节对齐的影响

    u速度影响

    非字节对齐访问会比字节对齐访问花费更多的硬件访问周期,因此前者的速度也会慢一些,但处理器的设计千差万别,架构层出不穷,不同处理器非字节对齐表现出的性能也不尽相同。

    下面是我测试的一组数据,测试中使用4字节对齐的指针访问非4字节对齐的地址:

    ARM7TDMI

    (ARMv4T)

    Cortex-M3

    (ARMv7-M)

    Pentium(R)

    Dual-Core CPU E6300

    是否支持硬件对齐

    硬件字节对齐访问时间

    19秒

    19秒

    23秒

    硬件非字节对齐访问时间

    63秒

    26秒

    26秒

    非字节访问效率

    (字节对齐 /非字节对齐)

    0.3

    0.73

    0.88

    注:上述3种处理器的测试数据不同,不能横向比较不同处理器的访问时间,只能纵向比较同一处理器的访问时间。

    从测试数据可以看出硬件非字节对齐访问确实要比硬件对齐访问速度要慢,但在不同的处理器架构上表现出的差异也是不同的。

    ARM7TDMI处理器不支持硬件非字节对齐访问,需要由软件指令实现硬件非字节对齐访问,只能使用在“非字节对齐的方法”一节中的方法,将1次4字节非字节对齐硬件访问打碎成4次1字节的硬件访问,因此与软件对应的硬件指令周期数成倍增加,这也就造成了该种处理器非字节对齐访问效率是如此之低,只有0.3,几乎达到四分之一的0.25。

    Cortex-M3处理器支持硬件非对齐访问,可以由一条软件指令实现1次4字节的非字节对齐硬件访问,至于硬件非字节对齐的处理部分则由硬件内部电路实现,这虽然要比硬件字节对齐访问花费更长的时间,但由于是硬件内部自动完成的,因此要比使用多条软件指令驱动硬件去完成要节省很多时间,因此效率也有了提升,达到0.73。

    Intel的X86处理器E6300也支持硬件非字节对齐访问,它的非字节对齐访问效率更高,达到0.88。前2种处理器属于低端领域的处理器,而E6300则属于高端处理器,这也许是它效率最高的原因。(前2种处理器没有cache,E6300有cache,但在测试中我应该避开了cache)

    u原子操作(atomic operation)影响

    对于单核处理器或者是处理器的一个内核来说,硬件指令是串行执行的,从软件层次来看,它是“不能被进一步分割的最小粒子”,因此一条硬件指令不会被多线程或中断所打断,这就是原子操作。

    对于不支持硬件非对齐访问的处理器若实现硬件非对齐访问就需要由多条硬件指令完成,比如说下面这个例子:

    __packed int* p;

    p = (int*)0x1001;

    *p = 0x12345678;

    为了使用4字节对齐的指针p实现对非4字节对齐的0x1001地址的访问使用了__packed,这样就将本可以使用一条硬件指令将4字节0x12345678一次写入0x1001~0x1004地址的这条指令拆分成4条对1字节访问的硬件指令,将数据0x78、0x56、0x34、0x12分别写入到0x1001、0x1002、0x1003、0x1004地址内,如果在2个线程中都有这种操作那么就破坏了原子操作,可能就会出问题。

    比如说一个计数值被存储在0x1001~0x1004这4个字节里,一个线程thread_add对这个计数值进行计数自加,另一个线程thread_read读取这个计数值。

    thread_add代码如下:

    __packed int* p= (int*) 0x1001;

    *p++;

    thread_read代码如下:

    __packed int* p= (int*)0x1001;

    int read;

    read = *p;

    如果当前的计数值是0x123456FF,thread_add线程则需要将其自加到0x12345700,thread_add线程使用4次字节读取将数据0x123456FF从内存中读取到内部寄存器中,并进行自加,变成了0x12345700。然后需要再使用4次字节写入将数据0x12345700写入到0x1001~0x1004中,thread_add线程先将0x00写入到0x1001中,如果这时候发生了线程切换,切换到了thread_read线程,那么thread_read线程将从地址0x1001~0x1004中读取计数值,但此时0x1001中的数值已经被thread_add线程改写为0x00,而0x1002~ 0x1004内的数值仍为原值,因此thread_read线程读取到的数据为0x12345600,这就出错了。

    对于支持硬件非字节对齐访问的处理器则不会有该问题存在,因为这种处理器的硬件非字节对齐访问是由硬件内部完成的,是一个原子操作,不会被线程打断,因此不会出错。

    这篇文档拖拖拉拉的写了4个多月,为了能说的更清楚让大家看的更明白,真的费了不少力气,挺不容易的。其中有些内容涉及到处理器内部机制,处理器架构又千差万别,我没有能力找到一个全面的权威说明,因此错误也许在所难免。如有问题请到我的博客反馈,我将尽力修正blog.sina.com.cn/ifreecoding

    展开全文
  • 在C语言中,结构是一种复合数据类型,其构成元素既可以是基本数据类型(如int、long、float等)的变量,也可以是一些复合数据类型(如数组、结构、联合等)的数据单元。
  • C语言 字节对齐

    2022-03-29 17:05:33
    结构体变量的首地址能够被其最宽基本类型成员的大小所整除; 结构体每个成员相对结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要...// char[*]多少都是按4字节对齐 struct stChar{ char a[5]; int b; .

    字节对齐 、pragma 、位域长度问题整理

    1. 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;
    2. 结构体每个成员相对结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节;
    3. 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节。
    #include <stdio.h>
    // 按结构体最宽数据类型int对齐
    // char[*]多少都是按4字节对齐
    struct stChar{
            char a[5];
            int b;
            char c;
    };
    
    // 按结构体最宽数据类型short对齐
    struct stShort{
            char a;
            short b;
    };
    
    // 按结构体最宽数据类型long对齐
    struct stLong{
            char a;
            long b;
    };
    
    // 按结构体最宽数据类型int对齐
    // 变量c的偏移量 要为自己大小的倍数
    #pragma pack(8) //为2时,sizeof为10.为8时sizeof为12 
    struct AA
    {
            int a;  
            char b; 
            short c; //长度2 偏移量要提升到2的倍数6;存放位置区间[6,7]
            char d; 
    };
    
    struct AAA
    {
            // 类型说明符 位域名: 位域长度
            int a:2; //变量a,4位长度,只使用两位长度 sizeof(AAA)为4
            char b:1;
    };
    
    int main()
    {
            struct stChar stChar1;
            struct stShort stShort1;
            struct stLong stLong1;
            struct AA stAA;
            struct AAA stAAA;
    
            printf("stChar = [%ld]\n", sizeof(stChar1));
            printf("stShort = [%ld]\n", sizeof(stShort1));
            printf("stLong = [%ld]\n", sizeof(stLong1));
            printf("stAA = [%ld]\n", sizeof(stAA));
            printf("stAAA = [%ld]\n", sizeof(stAAA));
            return 0}
    

    打印结果

    stChar = [16]
    stShort = [4]
    stLong = [16]
    stAA = [12]
    stAAA = [4]
    
    展开全文
  • C/C++字节对齐

    千次阅读 2022-03-25 16:46:54
    1. 字节对齐 字节对齐是字节按照一定规则在空间上排列。 现代计算机中内存空间的基础单元是字节(byte),从理论层面上讲,对于任何数据类型的变量的访问,都可以从任何地址开始。但是物理层面实现时,访问特定类型...

    1. 字节对齐

    字节对齐是字节按照一定规则在空间上排列。

    现代计算机中内存空间的基础单元是字节(byte),从理论层面上讲,对于任何数据类型的变量的访问,都可以从任何地址开始。但是物理层面实现时,访问特定类型变量的时候经常需要在特定的内存地址访问,一般时以2,4或8的倍数的字节块来读写内存。

    为什么要进行字节对齐?

    一句话来说:以牺牲空间的方式来减少时间的消耗。

    实际编程中,字节对齐的细节都是由编译器完成,但是需要知道变量是如何在内存中进行对齐的。

    2. C/C++ 结构体

    在C语言中,结构体可以用来存放一组不同类型的数据,结构体的定义形式为:

    struct 结构体名
    {
    	结构变量...
    };
    

    结构体变量定义:

    struct 结构体名 变量名;
    

    也可以在定义结构体的同时定义结构体变量:

    struct Student
    {
    	char name[24];
    	int student_id;
    }stu1, stu2; // 定义结构体变量stu1, stu2
    

    当只需要stu1, stu2两个变量,后面不再需要使用结构体名定义其他变量,可以在定义时不给出结构体名

    struct 
    {
    	char name[24];
    	int student_id;
    }stu1, stu2; // 定义结构体变量stu1, stu2
    

    C++中的结构体定义形式与C语言一样,只是在定义结构体变量时,不需要使用struct关键字

    Student stu1, stu2;
    

    typedef struct的区别

    在C语言中使用typedef定义结构名,在定义结构体变量时可以省去struct关键字

    typedef struct Student
    {
    	char name[24];
    	int student_id;
    } pStudent;// 别名
    
    // 定义结构体对象
    pStudent stu1; // 省去了struct
    

    使用typedef struct之后,C/C++定义结构体对象代码相同。

    3. 结构体对齐的公式

    1. #pragma pack(x)x和结构体中占用空间最大的成员做比较,取两者的最小值为n
    2. n值与结构体每个成员比较,得出结果列表为m[x]
    3. 根据每个成员的大小依次向内存中填充数据,要求填充成员的起始地址减去结构体起始地址的差值可以整除m[x],如不能整除则向后移动,直到可以整除再填充成员到内存
    4. 当全部成员填充完毕后所占用的字节数若不能整除n,则扩充内存至可以整除n为止
    #pragma pack(4)// 编译器将按照n个字节对齐
    struct data
    {
        int a;  // 4 bytes
        char b; // 4 bytes
        int c;  // 4 bytes
        short d;    // 4bytes
    };  // 16 bytes
    #pragma pack() // 编译器将取消自定义字节对齐方式
    

    在这里插入图片描述

    struct data
    {
        int a;  // 4 bytes
        char b; // 2 bytes
        short d;    // 2bytes
        int c;  // 4 bytes
        
    };  // 12 bytes
    

    在这里插入图片描述

    合理调整成员的位置,可以大大节省存储空间。但是需要在空间和可读性之间进行权衡。

    4. 跨平台传输

    由于不同平台对齐方式可能不同,可能导致同样的结构在不同的平台其大小可能不同,导致发送的数据可能出现错乱,引起严重问题。

    为了不同处理器之间能够正确处理结构体,有两种可选的处理方法:

    • 1字节对齐
    • 自己对结构 进行字节填充

    可以使用伪指令#pragma pack(n) 来使得结构之间按照一字节对齐

    #pragma pack(1)
    typedef struct
    {
        int a;
        char b;
        short d;
        int c;
    } DATA;
    #pragma pack()
    
    int main()
    {
        DATA data1 = {4, 'c', 2, 6};
        DATA data2 = {};
        memcpy(&data2, &data1, sizeof(DATA));
        
        cout << "sizeof(DATA) > : " << sizeof(DATA) << endl;
        cout << "data: " << data2.a << " " << data2.b << " " << data2.c << " " << data2.d << endl;
        return 0;
    }
    // sizeof(DATA) > : 11
    // data: 4 c 6 2
    

    对于单个结构体,如下的方法,可使其按一字节对齐

    typedef struct
    {
        int a;
        char b;
        short d;
        int c;
    } __attribute__ ((packed)) DATA;
    

    __attribute__ ((packed)):取消结构在编译过程中的优化对齐,即可以认为是一字节对齐

    人为填充方式

    typedef struct
    {
        int a;
        char b;
        char reserve[3];   // 填充
        int c;
        short d;
        char reserve1[2];  // 填充
    } DATA;
    

    参考链接

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

    2018-01-29 11:17:59
    结构体字节对齐规则,主要是介绍结构体字节对齐规则,内容有点长,但是很全面.
  • 大家好,我是小昭,因为在不同硬件平台数据传输时,遇到关于字节对齐的问题,索性就做了总结,以下是我对字节对齐的理解和小结,如有疑问请联系我。
  • amr-nb格式的使用,非字节对齐转换成字节对齐的源码。基于这份源码,可以理解两者格式的差别,并且实现代码的转换。最终使用opencore-amr库,可以实现解码。
  • 什么是字节对齐,为什么需要字节对齐

    万次阅读 多人点赞 2019-09-07 14:58:43
     另外字节对齐的作用不仅是便于cpu快速访问,同时合理的利用字节对齐可以==有效地节省存储空间==。  也即CPU一次访问时,要么读0x01~0x04,要么读0x05~0x08…硬件不支持一次访问就读到0x02~0x05  例:...
  • 字节对齐详解

    千次阅读 2020-08-22 00:23:14
    字节对齐简介 1. 基本原则 任何K字节的基本对象的地址必须是K的倍数。 基本对象:int、double、long、short等基本数据类型,不包括struct、union、class。 2. 结构体的字节对齐 一个结构体,首地址必须是结构体中...
  • STM32 终极字节对齐解析

    千次阅读 2021-11-09 22:09:31
    基本上用户定义的变量是几个字节就是几字节对齐,这个比较好理解。 uint8_t定义变量地址要1字节对齐。 uint16_t定义变量地址要2字节对齐。 uint32_t定义变量地址要4字节对齐。 uint64_t定义变量地址要8字节对齐。 ...
  • V5-417_RTX实验_内存管理(4字节对齐).7z

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 150,444
精华内容 60,177
关键字:

字节对齐