精华内容
下载资源
问答
  • 结构体字节对齐原则

    2012-03-05 15:46:56
    其实字节对齐的细节和具体编译器实现相关,但一般而言,满足三个准则:  1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;  2) 结构体每个成员相对于结构体首地址的偏移量都是成员大小的...
    其实字节对齐的细节和具体编译器实现相关,但一般而言,满足三个准则:
    
      1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;
      2) 结构体每个成员相对于结构体首地址的偏移量都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节;例如上面第二个结构体变量的地址空间。
      3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节。
    展开全文
  • struct结构体字节对齐原则及为什么要对齐?

    万次阅读 多人点赞 2019-01-06 11:30:21
    http://blog.sina.com.cn/s/blog_14ecf1a5b0102x27j.html ... //-------------------------------------------------------- 本文目录结构 |-为什么结构体内存对齐 |-结构体内...

    http://blog.sina.com.cn/s/blog_14ecf1a5b0102x27j.html

    https://blog.csdn.net/zhanghow/article/details/55262988

    //--------------------------------------------------------

    本文目录结构

    |-为什么结构体内存对齐

    |-结构体内存对齐规则

    |-具体举例

    //--------------------------------------------------------

    一、为什么结构体内存对齐

         现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特 定的内存地址访问,这就需要各种类型数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放,这就是对齐。
         对齐的作用和原因:各个硬件平台对存储空间的处理上有很大的不同。一些平台对某些特定类型的数据只能从某些特定地址开始存取。比如有些架构的CPU在访问 一个没有进行对齐的变量的时候会发生错误,那么在这种架构下编程必须保证字节对齐.其他平台可能没有这种情况,但是最常见的是如果不按照适合其平台要求对 数据存放进行对齐,会在存取效率上带来损失。比如有些平台每次读都是从偶地址开始,如果一个int型(假设为32位系统)如果存放在偶地址开始的地方,那 么一个读周期就可以读出这32bit,而如果存放在奇地址开始的地方,就需要2个读周期,并对两次读出的结果的高低字节进行拼凑才能得到该32bit数 据。显然在读取效率上下降很多。

           其实我们都知道,结构体只是一些数据的集合,它本身什么都没有。我们所谓的结构体地址,其实就是结构体第一个元素的地址。这样,如果结构体各个元素之间不存在内存对齐问题,他们都挨着排放的。对于32位机,32位编译器(这是目前常见的环境,其他环境也会有内存对齐问题),就很可能操作一个问题,就是当你想要去访问结构体中的一个数据的时候,需要你操作两次数据总线,因为这个数据卡在中间,如图:

    struct结构体字节对齐
     

           在上图中,对于第2个short数据进行访问的时候,在32位机器上就要操作两次数据总线。这样会非常影响数据读写的效率,所以就引入了内存对齐的问题。另外一层原因是:某些硬件平台只能从规定的地址处取某些特定类型的数据,否则会抛出硬件异常。

     

    二、结构体内存对齐的规则【未指定#pragma pack时】

          a.第一个成员起始于0偏移处;

          b.每个成员按其类型大小和指定对齐参数n中较小的一个进行对齐;

          c.结构体总长度必须为所有对齐参数的整数倍;

          d.对于数组,可以拆开看做n个数组元素。

         下表是Windows XP/DEV-C++和Linux/GCC中基本数据类型的长度和默认对齐模数。 

     

     

    char

    short

    int

    long

    float

    double

    long long

    long double

    Win-32

    长度

    1

    2

    4

    4

    4

    8

    8

    8

    模数

    1

    2

    4

    4

    4

    8

    8

    8

    Linux-32

    长度

    1

    2

    4

    4

    4

    8

    8

    12

    模数

    1

    2

    4

    4

    4

    4

    4

    4

    Linux-64

    长度

    1

    2

    4

    8

    4

    8

    8

    16

    模数

    1

    2

    4

    8

    4

    8

    8

    16

     

    三、具体举例

    例1:struct {
                     short a1;
                     short a2;
                     short a3;
                     }A;
              struct{
                     long a1;
                     short a2;
                     }B;

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

    sizeof(B) = 8; long为4,short为2,整个为8,因为规则b。

    例2:struct A{
                      int a;
                      char b;
                      short c;
                      };
           struct B{
                      char b;
                      int a;
                      short c;
                      };

    sizeof(A) = 8;sizeof(B) = 12。

    深究一下,为什么是这样,我们可以看看内存里的布局情况。

                                 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后面要补齐。

    例4:struct S1  

               {  

                  short a;  

                  long b;  

               };  

         struct S2  

              {  

        char c;  

        struct S1 d;  

        double e;  

              };  

           在Dev c++中,默认的是8字节对齐。我们分析下在4字节对齐的情况下输出的是,S2是20,S1是8,分析如图:

    struct结构体字节对齐
     

          在4字节对齐的情况中,有一个问题值得注意:就是图中画1的地方。这里面本应short是可以上去的。但是对于结构体中的结构体一定要十分警惕,S1是一体的,short已经由于long进行了内存对齐,后面还空了两个字节的内存,其实此时的short已经变成了4个字节了!!!即结构体不可拆,不管是多少字节对齐,他们都是一体的。所有的圈都变成了叉。所以说结构体只能往前篡位置,不能改变整体。

          我们在分析一些8字节对齐的情况,如图:

    struct结构体字节对齐

           以上讲的都是没有#pragma pack宏的情况,如果有#pragma pack宏,对齐方式按照宏的定义来。比如上面的结构体前加#pragma pack(1),内存的布局就会完全改变。sizeof(A) = 16; sizeof(B) = 32;

          有了#pragma pack(1),按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)呢?留给大家自己思考吧,相信没有问题。

    展开全文
  • 一 无#pragma pack 原则1:结构内部各个成员的首地址必然是自身大小的整数倍。 原则2:sizeof的最终...(以指定字节n与当前处理字节sizeof值比较) 原则4:整个sizeof的最终结果必然是min[n,结构内部最大成员],...

    一 无#pragma pack

    1. 原则1:结构内部各个成员的首地址必然是自身大小的整数倍。
    2. 原则2:sizeof的最终结果必然是结构内部最大成员的整数倍,不够补齐。

    二 有#pragma pack(n)

    1. 原则3:结构内部各个成员的首地址必然是min[n,自身大小]的整数倍。(以指定字节n与当前处理字节sizeof值比较)
    2. 原则4:整个sizeof的最终结果必然是min[n,结构内部最大成员],不够补齐。

    三 举个栗子
    情况1举例:—无#pragma pack 我这里主机64bit,指针占8个字节

    	typedef struct a
    	{
    		int *ptr;
    		char str[5];
    		int i;
    	}A;
    

    此时sizeof(A) = 【8+(5+3)+4】+4 = 24
    即sizeof(ptr) = 8,sizeof(str) = 5,于是由于原则1,补3个字节到str变量后,即5+3,sizeof(i) = 4。
    此时整个机构体大小为8+5+3+4=20。但是还有原则2,最后再补4个字节,于是整个结构体为24字节。
    情况2举例:—有#pragma pack(n)

    	#pragma pack(4)
    	typedef struct a
    	{
    		int *ptr;
    		char str[5];
    		int i;
    	}A;
    

    此处按照4字节进行补齐操作;
    此时sizeof(A) = 【8+(5+3)+4】 = 20
    5+3为原则3补充字节;【8+(5+3)+4】=20,根据原则4,此处不补充字节

    展开全文
  • 结构体默认的字节对齐一般满足三个准则: 结构体变量的首地址能够被其最宽基本类型成员的大小所整除; 结构体每个成员相对于结构体首地址的偏移量(offset)都是成员自身大小的整数倍,如有需要编译器会在...

    结构体默认的字节对齐一般满足三个准则:

    1. 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;

    2. 结构体每个成员相对于结构体首地址的偏移量(offset)都是成员自身大小的整数倍,如有需要编译器会在成员之间加上填充字节(internal adding);

    3. 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节(trailing padding)。

    http://www.cnblogs.com/bettermanlu/archive/2010/05/24/1743119.html



     

    展开全文
  • VC字节对齐全攻略 VC中下面几个结构体大小分别是多少呢 struct MyStruct {  double m4;  char m1;  int m3; };   struct MyStruct {  char m1;  double m4;  int m3; };   #pragma pack...
  • 结构体字节对齐

    2012-07-24 00:57:41
    下面针对在PC上Microsoft Visual Stdio上分析结构体字节对齐的问题。 在使用sizeof运算符计算结构体占用的内存大小时,不是简单的将成员变量所占用的内存大小直接相加。这中间涉及到内存字节对齐的问题。为什
  • C 结构体字节对齐规则

    千次阅读 2018-01-29 11:10:32
    文档下载:结构体字节对齐规则 原则1:数据成员的对齐规则(以最大的类型字节为单位)。 结构体(struct)的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存放在offset为该数据成员大小的整数倍的...
  • C语言结构体字节对齐

    2021-02-08 14:34:16
    对C语言结构体进行字节对齐的合理排列并不仅仅可以节省非常大的空间,最重要的是体现个人编程的良好习惯。 以N对齐方式 所谓的以N对齐方式纯属我瞎掰的,哈哈。 所有的结构体成员在定义结构体分配内存时都要与所有...
  • 结构体字节对齐小结

    2012-06-13 15:03:37
    结构体字节对齐小结 1.字节对齐的原因  一些平台对某些特定类型的数据,只能从特定地址开始存取。如有些存取是从偶地址开始,假设int(32位)的数据存在偶地址开始,则只需要一个周期就能拿到。但如果在奇地址开始...
  • C语言结构体字节对齐原则
  • 原则1 数据成员对齐规则:结构(struct或联合union)的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小的整数倍开始(比如int在32位机为4字节,则要从4的整数倍地址...
  • 下面总结了对齐原则,在没有#pragma pack宏的情况下: 原则1、普通数据成员对齐规则:第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小的整数倍开始(比如int在32位机为4字节,...
  • 原则1:数据成员的对齐规则(以最大的类型字节为单位)。 结构体(struct)的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存放在offset为该数据成员大小的整数倍的地方(比如int在32位机为4字节,...
  • C语言结构体对齐原则 Q:关于结构体的对齐,到底遵循什么原则? A:首先先不讨论结构体按多少字节对齐,先看看只以1字节对齐的情况: #include #include #define PRINT_D(intValue) printf(#int...
  • 结构体-字节对齐原则

    2020-03-16 21:02:30
    字节对齐的细节和具体的编译器有关,但一般而言,满足三个准则: 结构体变量的首地址能够被其最宽基本类型成员的大小所整除; 结构体每个成员相对于结构体首地址的偏移量都是成员大小的整数倍,如有需要编译器会在...
  • 如果pack改为16,这个复合类型大小为8,其成员最宽基本类型大小为4,那是多少字节对齐呢,是8字节对齐,这个时候就体现出来了,就是确定偏移量时,复合类型看整体大小。 ) 这里叙述起来有点拗口,思考起来也有点...
  • Q:关于结构体的对齐,到底遵循什么原则?...A:首先先不讨论结构体按多少字节对齐,先看看只以1字节对齐的情况: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 #include...
  • 作者:阿凡卢 ... 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究...A:首先先不讨论结构体按多少字节对齐,先看看只以1字节对齐的情况: ...
  • 结构体内存对齐原则

    2018-04-15 22:21:14
    C/C++中,最常见的数据类型有char,int,short,float ,double,long等,在各个系统或编译器中可能所占的字节数不太一样,此文...直接看它的对齐原则:在内存中,声明一个结构体对象它所占的内存中的数据成员是按声明...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 456
精华内容 182
关键字:

结构体字节对齐原则