博客
关于我
c语言结构体字节对齐详解
阅读量:367 次
发布时间:2019-03-05

本文共 1172 字,大约阅读时间需要 3 分钟。

1. 字节对齐是什么

在C语言的结构体中,字节对齐是指将结构体的各个成员占用内存的位置对齐到字节的整数倍。这种对齐方式确保了内存的有效利用,避免了内存碎片的产生。

以两个例子来说明:

  • 结构体 st1 包含 char name;double age;。在32位系统下,st1 占用16个字节(每个成员占用4个字节);而在64位系统下,st1 占用24个字节(每个成员占用4个字节)。
  • 结构体 st2 包含三个 char 成员,不管是32位还是64位系统,st2 都只占用3个字节。

从上述例子可以看出,结构体成员的字节对齐规则如下:

  • 如果所有成员的字节长度都未超过系统基本字节单位(32位为4字节,64位为8字节),则以最长成员的字节数为对齐基数。
  • 如果某个成员的字节长度超过了系统基本字节单位,则按系统基本字节单位进行对齐。
  • 注意:并非所有系统都严格按照字节单位对齐。32位系统对齐4字节,64位系统对齐8字节。


    2. 为什么需要字节对齐

    CPU一次可以读取的内存数据量由数据总线宽度决定。例如:

    • 16位数据总线一次可以读取2个字节。
    • 32位数据总线一次可以读取4个字节。

    如果不进行字节对齐,CPU在访问结构体中的不同成员时,可能会跨页读取,导致效率降低。例如:

    struct st3 {    char a;    int b;};

    在32位系统下,a 占用1字节,b 占用4字节。若不对齐,b 的内存分布为 0x00000002-0x000000040x00000005,导致CPU需要两次读取。字节对齐后,b 占用连续的4个字节,CPU一次性读取,效率提升。


    3. 手动设置对齐

    在以下情况下需要手动设置字节对齐:

  • 跨平台通信:如设备间通过网络通信共享结构体,需确保两端结构体对齐一致。
  • 硬件驱动开发:如寄存器结构对齐。
  • 手动设置对齐方式有两种:

  • 使用预编译标识:
    #pragma pack(n)  // n为对齐字节数struct st3 {    char a;    int b;};#pragma pack()  // 取消对齐
  • 结构体属性设置:
    struct bbb {    char a;    int b;} __attribute__((packed));  // 强制不带填充位

  • 4. 结构体比较方法

    使用 memcpy 比较结构体时,需注意:

  • 设置对齐方式为1字节,避免填充位问题。
  • 事先对结构体进行初始化。
  • 示例代码:

    #include 
    memcpy(char *dest, const char *src, int len);

    总结

    字节对齐是保证结构体内存布局一致性的重要技术,尤其在多平台通信和驱动开发中至关重要。通过预编译标识或结构体属性手动设置对齐,可以实现跨平台兼容。

    转载地址:http://pccwz.baihongyu.com/

    你可能感兴趣的文章
    笨办法学Python之将对象名的字符串类型,转化成相应对象
    查看>>
    ArduPilot源码极速下载手册(一文告别github慢速问题)
    查看>>
    聊一聊那些应该了解的大佬(飞控,人工智能方向)
    查看>>
    ArduPilot+mavros+gazebo+QGC联合仿真初体验
    查看>>
    px4调试bug--添加mavlink_log_info信息
    查看>>
    redis替换字符串命令
    查看>>
    redis向数组中添加值并查看数组长度
    查看>>
    python3基础梳理11python中模块和包
    查看>>
    求出1/1-1/2+1/3-1/4…..1/100的和
    查看>>
    JS编写一个函数,计算三个不同数字的大小,按从小到大顺序打印(穷举法)
    查看>>
    js设置小球的缓冲运动
    查看>>
    jQuery实现轮播图效果
    查看>>
    restFUL
    查看>>
    mybatis中like的注意
    查看>>
    sqlplus的基本使用
    查看>>
    oracle删除表重复数据
    查看>>
    EditText获取焦点并显示软键盘,Textview字间距,EditText输入监听判断不大于,处理倒计时
    查看>>
    Oracle删除主表数据
    查看>>
    js中两种定时器,setTimeout和setInterval实现验证码发送
    查看>>
    Oracle常用SQL
    查看>>