首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >[C&C++]C语言字节对齐#pragma pack()

[C&C++]C语言字节对齐#pragma pack()

作者头像
祥知道
发布2020-03-10 15:48:27
1.3K0
发布2020-03-10 15:48:27
举报
文章被收录于专栏:祥的专栏祥的专栏
  1. 扩展概念

1.现象

1.1. 测试代码

#include <iostream>
using namespace std;


//默认对齐方式
typedef struct
{
    double a;//8个字节
    char   b;//1个字节
    float  c;//4个字节
}DataType;


//8字节对齐方式
#pragma pack(push)
#pragma pack(8)
typedef struct
{
    double a;//8个字节
    char   b;//1个字节
    float  c;//4个字节
}DataType_8;
#pragma pack(pop)

//4字节对齐方式
#pragma pack(push)
#pragma pack(4)
typedef struct
{
    double a;//8个字节
    char   b;//1个字节
    float  c;//4个字节
}DataType_4;
#pragma pack(pop)

//2字节对齐方式
#pragma pack(push)
#pragma pack(2)
typedef struct
{
    double a;//8个字节
    char   b;//1个字节
    float  c;//4个字节
}DataType_2;
#pragma pack(pop)

//1字节对齐方式
#pragma pack(push)
#pragma pack(1)
typedef struct
{
    double a;
    char   b;
    float  c;
}DataType_1;
#pragma pack(pop)


int main()
{

    cout << "sizeof( DataType ) = " << sizeof(DataType) << endl;
    cout << "sizeof( DataType_1 ) = " << sizeof(DataType_1) << endl;
    cout << "sizeof( DataType_2 ) = " << sizeof(DataType_2) << endl;
    cout << "sizeof( DataType_4 ) = " << sizeof(DataType_4) << endl;
    cout << "sizeof( DataType_8 ) = " << sizeof(DataType_8) << endl;



    return 0;
}

1.2. 结果

sizeof( DataType ) = 16
sizeof( DataType_1 ) = 13
sizeof( DataType_2 ) = 14
sizeof( DataType_4 ) = 16
sizeof( DataType_8 ) = 16

1.3. 注意

各家编译器(VSgcc)对与packpop的解释和支持都是不一样的。

Visual Studio 2013 http://msdn.microsoft.com/en-us/library/2e70t5y1(v=vs.120).aspx

具体可以看看这个博文:http://blog.chinaunix.net/uid-14949191-id-3969367.html

不过在下认为,最主要的还是要多测试,如果换了编译环境,一定要测试先行,血的教训。

2. 相关概念

字节对齐:

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

结构体对齐:

在C语言中,结构体是种复合数据类型,其构成元素既可以是基本数据类型(如int、long、float等)的变量,也可以是一些复合数据类型(如数组、结构体、联合等)的数据单元。编译器为结构体的每个成员按照其自然边界(alignment)分配空间。各成员按照它们被声明的顺序在内存中顺序存储,第一个成员的地址和整个结构的地址相同。 字节对齐的问题主要就是针对结构体。

引用一些博客博文说明

四个重要的基本概念:

  1. 数据类型自身的对齐值:char型数据自身对齐值为1字节,short型数据为2字节,int/float型为4字节,double型为8字节。
  2. 结构体或类的自身对齐值:其成员中自身对齐值最大的那个值。
  3. 指定对齐值:#pragma pack (value)时的指定对齐值value。
  4. 数据成员、结构体和类的有效对齐值:自身对齐值和指定对齐值中较小者,即有效对齐值=min{自身对齐值,当前指定的pack值}。

结构体字节对齐的细节和具体编译器实现相关,但一般而言满足三个准则:

  1. 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;
  2. 结构体每个成员相对结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节(internal adding);
  3. 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节{trailing padding}。

3. 扩展概念

位域对齐

有些信息在存储时,并不需要占用一个完整的字节,而只需占几个或一个二进制位。例如在存放一个开关量时,只有0和1两种状态,用一位二进位即可。为了节省存储空间和处理简便,C语言提供了一种数据结构,称为“位域”或“位段”。 位域是一种特殊的结构成员或联合成员(即只能用在结构或联合中),用于指定该成员在内存存储时所占用的位数,从而在机器内更紧凑地表示数据。每个位域有一个域名,允许在程序中按域名操作对应的位。这样就可用一个字节的二进制位域来表示几个不同的对象。

可以继续查看相关博文,在下现在没有对此没有需求,先Mark一下:相关博文

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.现象
    • 1.1. 测试代码
      • 1.2. 结果
        • 1.3. 注意
        • 2. 相关概念
        • 3. 扩展概念
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档