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

    2019-04-12 15:26:06
    解析C语言结构体对齐(内存对齐问题) C语言结构体对齐也是老生常谈的话题了。基本上是面试题的必考题。内容虽然很基础,但一不小心就会弄错。写出一个struct,然后sizeof,你会不会经常对结果感到奇怪?sizeof的结果...

    解析C语言结构体对齐(内存对齐问题)
    C语言结构体对齐也是老生常谈的话题了。基本上是面试题的必考题。内容虽然很基础,但一不小心就会弄错。写出一个struct,然后sizeof,你会不会经常对结果感到奇怪?sizeof的结果往往都比你声明的变量总长度要大,这是怎么回事呢?
    开始学的时候,也被此类问题困扰很久。其实相关的文章很多,感觉说清楚的不多。结构体到底怎样对齐?
    有人给对齐原则做过总结,具体在哪里看到现在已记不起来,这里引用一下前人的经验(在没有#pragma pack宏的情况下):
    原则1、数据成员对齐规则:结构(struct或联合union)的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小的整数倍开始(比如int在32位机为4字节,则要从4的整数倍地址开始存储)。
    原则2、结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储。(struct a里存有struct b,b里有char,int,double等元素,那b应该从8的整数倍开始存储。)
    原则3、收尾工作:结构体的总大小,也就是sizeof的结果,必须是其内部最大成员的整数倍,不足的要补齐。
    这三个原则具体怎样理解呢?我们看下面几个例子,通过实例来加深理解。
    例1:struct {
    short a1;
    short a2;
    short a3;
    }A;

          struct{
                 long a1;
                 short a2;
                 }B;
          sizeof(A) = 6; 这个很好理解,三个short都为2。
          sizeof(B) = 8; 这个比是不是比预想的大2个字节?long为4,short为2,整个为8,因为原则3。
    例2:struct A{
                  int a;
                  char b;
                  short c;
                  };
    
         struct B{
                  char b;
                  int a;
                  short c;
                  };
       sizeof(A) = 8; int为4,char为1,short为2,这里用到了原则1和原则3。
       sizeof(B) = 12; 是否超出预想范围?char为1,int为4,short为2,怎么会是12?还是原则1和原则3。
    

    深究一下,为什么是这样,我们可以看看内存里的布局情况。
    a b c
    A的内存布局:1111, 1*, 11
    b a c
    B的内存布局:1***, 1111, 11**
    其中星号表示填充的字节。A中,b后面为何要补充一个字节?因为c为short,其起始位置要为2的倍数,就是原则1。c的后面没有补充,因为b和c正好占用4个字节,整个A占用空间为4的倍数,也就是最大成员int类型的倍数,所以不用补充。
    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(A) = 24; 这个比较好理解,int为4,double为8,float为4,总长为8的倍数,补齐,所以整个A为24。
    sizeof(B) = 48; 看看B的内存布局。
    e f g h i
    B的内存布局:11
    *, 1111, 11111111, 11 * * * * * , 1111 * * *, 11111111, 1111 * * * *
    i其实就是A的内存布局。i的起始位置要为24的倍数,所以h后面要补齐。把B的内存布局弄清楚,有关结构体的对齐方式基本就算掌握了。
    以上讲的都是没有#pragma pack宏的情况,如果有#pragma pack宏,对齐方式按照宏的定义来。比如上面的结构体前加#pragma pack(1),内存的布局就会完全改变。sizeof(A) = 16; sizeof(B) = 32;
    有了#pragma pack(1),内存不会再遵循原则1和原则3了,按1字节对齐。没错,这不是理想中的没有内存对齐的世界吗。
    a b c
    A的内存布局:1111, 11111111, 1111
    e f g h i
    B的内存布局:11, 1111, 11111111, 11 , 1111, 11111111, 1111
    那#pragma pack(2)的结果又是多少呢?#pragma pack(4)呢?留给大家自己思考吧,相信没有问题。
    还有一种常见的情况,结构体中含位域字段。位域成员不能单独被取sizeof值。C99规定int、unsigned int和bool可以作为位域类型,但编译器几乎都对此作了扩展,允许其它类型类型的存在。
    使用位域的主要目的是压缩存储,其大致规则为:
    1) 如果相邻位域字段的类型相同,且其位宽之和小于类型的sizeof大小,则后面的字段将紧邻前一个字段存储,直到不能容纳为止;
    2) 如果相邻位域字段的类型相同,但其位宽之和大于类型的sizeof大小,则后面的字段将从新的存储单元开始,其偏移量为其类型大小的整数倍;
    3) 如果相邻的位域字段的类型不同,则各编译器的具体实现有差异,VC6采取不压缩方式,Dev-C++采取压缩方式;
    4) 如果位域字段之间穿插着非位域字段,则不进行压缩;
    5) 整个结构体的总大小为最宽基本类型成员大小的整数倍。
    还是让我们来看看例子。
    例4:struct A{
    char f1 : 3;
    char f2 : 4;
    char f3 : 5;
    };
    a b c
    A的内存布局:111, 1111 *, 11111 * * *
    位域类型为char,第1个字节仅能容纳下f1和f2,所以f2被压缩到第1个字节中,而f3只能从下一个字节开始。因此sizeof(A)的结果为2。
    例5:struct B{
    char f1 : 3;
    short f2 : 4;
    char f3 : 5;
    };
    由于相邻位域类型不同,在VC6中其sizeof为6,在Dev-C++中为2。
    例6:struct C{
    char f1 : 3;
    char f2;
    char f3 : 5;
    };
    非位域字段穿插在其中,不会产生压缩,在VC6和Dev-C++中得到的大小均为3。
    考虑一个问题,为什么要设计内存对齐的处理方式呢?如果体系结构是不对齐的,成员将会一个挨一个存储,显然对齐更浪费了空间。那么为什么要使用对齐呢?体系结构的对齐和不对齐,是在时间和空间上的一个权衡。对齐节省了时间。假设一个体系结构的字长为w,那么它同时就假设了在这种体系结构上对宽度为w的数据的处理最频繁也是最重要的。它的设计也是从优先提高对w位数据操作的效率来考虑的。有兴趣的可以google一下,人家就可以跟你解释的,一大堆的道理。
    最后顺便提一点,在设计结构体的时候,一般会尊照一个习惯,就是把占用空间小的类型排在前面,占用空间大的类型排在后面,这样可以相对节约一些对齐空间。

    展开全文
  • 详解C语言结构体对齐(内存对齐问题)C语言结构体对齐也是老生常谈的话题了。内容虽然很基础,但一不小心就会弄错。我在刚开始接触的时候也会是很迷糊,通过编译器运行的结果总是和自己的不一样,使自己很苦恼。在网上...

    详解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;

    };

    structB

    {

    long a1;

    short a2;

    };

    sizeof(structA) = 6; 这个很好理解,三个short都为2。

    sizeof(structB) = 8; 这个比是不是比预想的大2个字节?long为4,short为2,整个为8,因为原则3。(结构体的总大小,也就是sizeof的结果,必须是其内部最大成员的整数倍,不足的要补齐)

    运行结果图如下:

    0818b9ca8b590ca3270a3433284dd417.png

    0818b9ca8b590ca3270a3433284dd417.png

    例2:

    struct A

    {

    int a;

    char b;

    short c;

    };

    struct B

    {

    char b;

    int a;

    short c;

    };

    sizeof(structA) = 8; int为4,char为1,short为2,这里用到了原则1和原则3。

    sizeof(structB) = 12; 是否超出预想范围?char为1,int为4,short为2,怎么会是12?还是原则1和原则3。

    大家可能一个规则会用,但是将原则结合起来就有点犯迷糊了,下面写一下内存的布局。abc

    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类型的倍数,所以不用补充。

    Bac

    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个字节。

    运行结果如下图:

    0818b9ca8b590ca3270a3433284dd417.png

    0818b9ca8b590ca3270a3433284dd417.png

    再看一个结构中含有结构成员的例子:

    例3:struct A

    {

    int a;

    double b;

    float c;

    };

    struct B

    {

    char e[2];

    int f;

    double g;

    short h;

    struct A i;

    };

    sizeof(structA) = 24; 这个比较好理解,int为4,double为8,float为4,总长为8的倍数,补齐,所以整个A为24。

    A的布局为:

    a              b       c

    1111* * * *, 11111111, 1111 * * * *

    sizeof(structB) = 48; 看看B的内存布局。

    efg        h

    B的内存布局:11* *,   1111,   11111111, 11 * * * * * *,

    i

    1111* * * *, 11111111, 1111 * * * *      i其实就是A的内存布局。i的起始位置要为24的倍数,所以h后面要补齐。把B的内存布局弄清楚,有关结构体的对齐方式基本就算掌握了。

    展开全文
  • C语言结构体对齐规则与0字节数组@[TOC](C语言结构体对齐规则与0字节数组)C语言结构体对齐规则对齐规则说明 C语言结构体对齐规则 不同的编译器和系统默认的对齐规则会有差异,这里我使用的32bit的MinGW。 对齐规则...

    C语言结构体对齐规则

    不同的编译器和系统默认的对齐规则会有差异,这里我使用的32bit的MinGW。

    1、结构对齐

    对齐规则说明:

    • 规则一:struct内的第一个成员在偏移地址0处,随后成员的偏移地址在其本身字节大小整数倍处。
    • 规则二:struct的总大小为内部最大成员的整数倍
    • 规则三:当A结构内含有结构B时,B在A中的偏移地址为B结构成员内最大元素的整数倍

    示例1:

    #include <stdio.h>
    #include <stdlib.h>
    #include <stdint.h>
    
    #define debug_printf(value) printf(#value " ---==> %d\n", value)
    
    #define struct_member_offset(struct, member) (((char *)(&(((struct *)0)->member))) - ((char *)0))
    
    typedef struct
    {
    	uint8_t  a;
    	uint32_t b;
    	uint8_t  c;
    	uint8_t  d;
    }test_t;
    
    int main()
    {
    	int a = struct_member_offset(test_t, a);
    	int b = struct_member_offset(test_t, b);
    	int c = struct_member_offset(test_t, c);
    	int d = struct_member_offset(test_t, d);
    	debug_printf(sizeof(test_t));
    	debug_printf(a);
    	debug_printf(b);
    	debug_printf(c);
    	debug_printf(d);
    	return 0;
    }
    
    

    输出结果:
    在这里插入图片描述
    解析:

    • a为第一个成员在偏移地址0处
    • b成员类型为无符号整形占用四字节,根据规则一b要对齐到4字节地址处,所以偏移地址为4,相当于在a成员后面补齐了3字节
    • c和d成员大小都为1字节,根据规则一要对齐到1字节,所以c偏移为9,d偏移为10
    • 四个成员目前所占用的空间加起来是10字节,但是!此时还没完!根据规则二结构体的总大小为结构内最大成员的整数倍,test_t这个结构内最大成员是b占用4字节,所以10字节还要补齐2字节去对齐4字节,所以sizeof(test_t)=12。

    示例二:

    现在将d成员改为uint64类型:

    typedef struct
    {
    	uint8_t  a;
    	uint32_t b;
    	uint8_t  c;
    	uint64_t  d;
    }test_t;
    

    输出结果:

    还是根据规则解析:

    • a在偏移地址0处
    • b在4处
    • c在8处
    • abc所占用的空间为9个字节,d为uint64类型占8个字节,所以要对齐到8字节处,也就是偏移地址16处,相当于c成员后补齐了7字节。
    • 目前四个成员所占用的空间为24字节,24是d类型的倍数大小,所以sizeof(test_t)=24

    示例三:
    现在将结构改为如下,多了一个数据

    typedef struct
    {
    	uint8_t  a;
    	uint32_t b;
    	uint8_t c[3];
    	uint8_t  d;
    	uint64_t  e;
    }test_t;
    
    

    输出结果:
    在这里插入图片描述
    c成员为3字节,占用偏移地址8,9,10三个空间,所以总大小还是24。


    示例四:
    将结构改为如下,现在test_t结构内包含结构sub_t。

    typedef struct
    {
    	uint8_t sub_a;
    	uint32_t sub_b;
    }sub_t;
    
    typedef struct
    {
    	uint8_t  a;
    	uint32_t b;
    	sub_t c;
    	uint8_t  d;
    	uint64_t  e;
    }test_t;
    

    输出结果:
    在这里插入图片描述

    解析:

    • 根据规则一和二解析sizeof(sub_t)=8字节
    • 根据规则三确定sub_t在test_t中的偏移地址肯定是4的整数倍处,所以c这个结构成员偏移地址为8
    • d偏移地址为17
    • e偏移地址为24
    • sizeof(test_t)=32

    2、字节为0的数组与结构体

    先看一下0字节数组的大小:

    int main()
    {
    	int array[0];
    	debug_printf(sizeof(array));
    	return 0;
    }
    

    输出结果:

    sizeof(array) ---==> 0
    

    说明0字节数据占用空间为0,那么看下面这个例子:

    #include <stdio.h>
    #include <stdlib.h>
    #include <stdint.h>
    
    #define debug_printf(value) printf(#value " ---==> %d\n", value)
    
    #define struct_member_offset(struct, member) (((char *)(&(((struct *)0)->member))) - ((char *)0))
    
    typedef struct
    {
    	uint8_t  a;
    	uint32_t b;
    	uint8_t  c;
    	uint64_t  d[0];
    }test_t;
    
    int main()
    {
    	int a = struct_member_offset(test_t, a);
    	int b = struct_member_offset(test_t, b);
    	int c = struct_member_offset(test_t, c);
    	int d = struct_member_offset(test_t, d);
    	debug_printf(sizeof(test_t));
    	debug_printf(a);
    	debug_printf(b);
    	debug_printf(c);
    	debug_printf(d);
    	return 0;
    }
    

    输出结果:
    在这里插入图片描述
    !!奇怪的问题出现了!!

    但道理说d成员占用空间为0,sizeof(test_t)应该是12才对,但是sizeof(test_t)却是16!!

    原因:d成员虽然占用空间为0,但是他是uint64类型的,结构体的总大小是按照内部最大成员进行对齐的!test_t对齐到了8字节,所以sizeof(test_t)的大小为16字节!


    ends…

    展开全文
  • C语言 结构体对齐

    2018-09-17 11:01:24
    1.9结构体在内存中的存储与字节对齐 结构体的大小本应该是所有成员的类型大小之和,但因为引入字节...出于效率的考虑,C语言引入了字节对齐机制,结构体变量占据的内存单元的个数应当大于等于其内部所有数据成员占...

    1.9结构体在内存中的存储与字节对齐

    结构体的大小本应该是所有成员的类型大小之和,但因为引入字节对齐的缘故,导致结构体真实的大小一般大于等于所有成员大小之和。成员在结构体中的位置对结构体的大小可能会造成影响。

    对于MyStruct1,内存分配如下: 
    这里写图片描述

    1.9.1 结构体字节对齐机制

    出于效率的考虑,C语言引入了字节对齐机制,结构体变量占据的内存单元的个数应当大于等于其内部所有数据成员占据内存单元数的和。 
    一般来说,不同的编译器字节对齐机制有所不同,但还是有以下3条通用准则: 
    (1) 结构体的大小能够整除其最宽基本类型成员的大小; 
    (2) 结构体每个成员相对于结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节(internal adding); 
    (3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节(trailing padding)。

    说明: 
    字节对齐第(3)条准则提及最宽基本类型的概念,所谓基本类型是指像char、short、int、float、double这样的内置数据类型。“数据宽度”就是指其sizeof的大小。诸如结构体、共用体和数组等都不是基本数据类型。

    注意:如下示例都是在32位编译环境下测试的。

    示例:

    struct MyStruct1
    {
        char ch1;
        char ch2; //  两者不足4,填充
        int i1;   // 4
        int i2;  // 4
    };
    sizeof(struct MyStruct1)  // 12 
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    
    struct MyStruct2
    {
        int i1;  // 4
        char ch1;
        char ch2; // 两者不足4,填充
        char chs[11];  // 12
    };
    
    sizeof(struct MyStruct2)  // 20
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    struct MyStruct3
    {
        char ch1;  //4 
        int i;  // 4
        char chs[9]; // 12
    };
    sizeof(struct MyStruct3) // 20
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    struct MyStruct4
    {
        char ch1;  // 8
        double db; // 8
        int i; // 4
        char chs[9]; // 12
    
    };
    sizeof(struct MyStruct4)  // 32
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    struct MyStruct5
    {
        int i;  // 4
        short s;  // 4
        char chs[11]; // 12
    };
    sizeof(struct MyStruct5)  // 20
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    1.9.2 结构体嵌套结构体

    当结构体嵌套结构体时,字节对齐所参考的最宽基本成员不局限与当前结构体,可能是所包含的结构体中的最宽基本成员。

    struct MyStruct7
    {
        int i;
        char ch;
    };
    
    struct MyStruct8
    {
        struct MyStruct7  s;   //此时参考的是MyStruct7中最宽的int
        char ch;
    
    };
    
    printf("%d\n", sizeof(struct MyStruct8));  //输出12
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    1.9.3 offsetof(s,m)

    在stddef.h 头文件中,可以使用offsetof来看某个元素相对结构体的起始位置偏移了多少个字节

    typedef struct MyStruct6
    {
        char ch;
        int i;
        double d;
    };
    ...
    printf("%d,%d\n", sizeof(struct MyStruct6),offsetof(struct MyStruct6, i)); //输出 16,4
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    1.9.4 手动设置成员对齐

    在vs2015中,依次点击 项目 –> 结构体 属性 –> C/C++ –> 代码生成,在如下界面的结构成员对齐选项进行设置: 
    这里写图片描述

    例:

    struct MyStruct7
    {
        int i;
        char ch;
    };
    ... 
    printf("%d\n", sizeof(struct MyStruct7));
    
    // 当我们设置对齐字节为2字节时
    // 输出为6
    
    // 当我们设置对齐字节为8字节时
    // 输出为8
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    注意: 当我么设置的字节数小于结构体最宽基本成员时,以设置的为主;当设置的字节数大于结构体最宽成员时,以结构体最宽基本成员的大小为主:总结即是两者按最小的来计算

    展开全文
  • C语言结构体对齐、枚举、宏、联合体结构体对齐问题枚举常量与宏的区别联合体和结构体区别C和C++结构体区别 结构体对齐问题 关于结构体对齐问题请阅读:结构体对齐规则及举例 系统指定类型的大小与系统有关,这里取 ...
  • c语言结构体对齐

    2010-11-03 14:02:00
    <br />C语言结构体对齐也是老生常谈的话题了。基本上是面试题的必考题。结构体到底怎样对齐?下面总结了对齐原则,在没有#pragma pack宏的情况下: 原则1、普通数据成员对齐规则:第一个数据成员放在...
  • linux C语言结构体对齐

    2016-08-03 15:23:00
    linux C语言结构体对齐 linux C语言结构体对齐(32位对齐) posted on 2016-08-03 15:23 xuhaohunter 阅读(...) 评论(...) 编辑 收藏 var allowComments=true,...
  • c语言结构体对齐

    千次阅读 2010-10-10 15:09:00
    C语言结构体对齐也是老生常谈的话题了。基本上是面试题的必考题。内容虽然很基础,但一不小心就会弄错。写出一个struct,然后sizeof,你会不会经常对结果感到奇怪?sizeof的结果往往都比你声明的变量总长度要大,这...
  • C语言结构体对齐.pdf

    2019-09-10 11:20:28
    C 语言结构体对齐也是老生常谈的话题了。基本上是面试题的必考题。内容 虽然很基础,但一不小心就会弄错。写出一个 struct,然后 sizeof,你会不会经 常对结果感到奇怪? sizeof的结果往往都比你声明的变量总长度要...
  • C语言中结构体对齐,c语言结构体对齐,c语言结构体内存对齐,c语言结构体字节对齐,c语言中的结构体,c语言中结构体的使用,c语言中结构体,c语言中结构体的定义,c语言中结构体定义,c语言结构体C 语言中结构体对齐(来自网络...
  • 详解C语言结构体对齐(内存对齐问题)        C语言结构体对齐也是老生常谈的话题了。内容虽然很基础,但一不小心就会弄错。我在刚开始接触的时候也会是很迷糊,通过编译器运行的结果总是和自己的不一样,使...
  • C语言结构体对齐问题详解 测试环境32位机 WinXP: 编译器VC6(MS cl.exe ) 和 mingw32-gcc-4.5.2   1 结构体数据对齐(没有#pragma pack()宏定义) 结构体对齐可以总结为三个基本原则 ①数据成员...
  • 30.C语言结构体对齐访问

    千次阅读 2016-04-04 13:05:05
    30.1.C语言之结构体概述 30.2.从数组到结构体的进化 30.3.访问结构体和数组中的...结构体对齐访问的来龙去脉 30.5.结构体对齐的规则和运算 30.6.gcc支持但不推荐的对齐指令 30.7.gcc推荐的对齐指令 30.8.参考阅读博客
  • C语言结构体之内存对齐1、什么是内存对齐首先看一个例子,下面有一个结构体:struct structTest1{char c1;short s;char c2;int i;};假设这个结构体成员在内存中是紧凑排列的,那么c1的存储地址就是0,s的存储地址是1...
  • C语言结构体对齐问题(内存对齐问题)—没有#praggma pack宏的情况下 参考博文 三大原则 原则1:数据成员对齐原则:结构(struct或联合union)的数据成员,第一个数据成员放在offset的为0的地方,以后的每个数据...
  • C语言结构体对齐总结

    2016-10-04 18:51:20
    结构体对齐包括两个方面的含义 1)结构体总长度;  2)结构体内各数据成员的内存对齐,即该数据成员相对结构体的起始位置; 一、字节对齐的原因大致是如下两条 1、平台原因(移植原因):不是所有的硬件平台都能访问
  • c语言结构体对齐规则

    2017-09-07 09:11:44
    1.第一个成员在与结构体变量偏移量为0的地址处。 2.其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。 //对齐数 = 编译器默认的一个对齐数 与...4.如果嵌套了结构体的情况,嵌套的结构体对齐到自己的对齐数
  • C语言结构体对齐也是老生常谈的话题了。基本上是面试题的必考题。结构体到底怎样对齐?下面总结了对齐原则,在没有#pragma pack宏的情况下: 原则1、普通数据成员对齐规则:第一个数据成员放在offset为0的地方,以后...
  • 在通信协议的开发过程中,有时会利用结构体构造报文某些字段,这就有可能会涉及到结构体对齐的问题。如果稍有不慎,会因结构体使用不当导致功能受到严重影响。 以下面一段代码为例: #include <stdio.h> #...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 44,558
精华内容 17,823
关键字:

c结构体对齐