IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C语言结构体对齐 -> 正文阅读

[C++知识库]C语言结构体对齐

计算机内存是以字节(Byte)为单位划分的,理论上CPU可以访问任意编号的字节,但实际情况并非如此。cpu一次能读取多少内存要看数据总线是多少位,如果是16位,则一次只能读取2个字节,如果是32位,则可以读取4个字节,并且cpu不能跨内存区间访问。
假设有一个整型的数据a的首地址不是4的倍数,不妨设为0X00FFFFF3,则该整型数据存储在地址范围为0X00FFFFF3~0X00FFFFF6的存储空间中,而CPU每次只能对4的倍数内存地址进行读取,因此想读取a的数据,CPU要分别在0X00FFFFF0和0X00FFFFF4进行两次内存读取,而且还要对两次读取的数据进行处理才能得到a的数据。
加入采取对齐的方式,将数据a的首地址放到0X00FFFFF4,只需一次读取一次就可以得到数据a,所以说,字节对齐的根本原因其实在于cpu读取内存的效率问题,对齐以后,cpu读取内存的效率会更快。但采取对齐以后0X00FFFFF3这个地址就会浪费掉,对齐就是安排对象在内存中的位置,以使效率最大化,但这是以牺牲空间为代价的,这就需要根据实际情况去选择。

结构体对齐的条件根据CPU、操作系统,还有编译器而决定的,一般情况下,32位下是按照4个字节来对齐,64位下则是按照8个字节来对。

结构体对齐规则

  • 结构体成员,除了第一个是始终放在最开始的地方,其它数据成员的地址必须是它本身大小或对齐参数两者中较小的一个的倍数。(对齐参数可以是通过编译命令#pragma pack(n)来指定,或者是系统默认的对齐参数)
  • 结构体嵌套,即结构体作为成员,则结构体成员要从其内部最大元素大小的的整数倍地址开始存储。(struct a里存有char,int,struct b,b里有char,int,double等,那b应该从8的整数倍开始存储)
#include <stdio.h>

typedef struct
{
        char s1;
        double s2;
        char s3;
}a;

int main(char argc, char *argv[])
{
        printf("%ld\n", sizeof(a));
        return 0;
}

ubuntu64位下编译运行得到结果:24
ubuntu32位下编译运行得到结果:16
64位下,s1占1字节,后面填充7字节,s2占8个字节,s3占1字节,后面填充7字节,共占24字节。
32位下,s1占1字节,后面填充3字节,s2占8个字节,s3占1字节,后面填充3字节,共占16字节。

#include <stdio.h>

typedef struct
{
        char s1;
        double s2;
        char s3;
}a;

typedef struct
{
        char t1;
        a t2;
        double t3;
}b;

int main(char argc, char *argv[])
{
        printf("%ld\n", sizeof(b));
        return 0;
}

ubuntu64位下编译运行得到结果:40
ubuntu32位下编译运行得到结果:28
64位下,t1占1字节,后面填充7字节,t2中s1占1个字节,后面填充7个字节,t2中s2占8个字节,t2中s3占1个字节,后面填充7个字节,t3占8个字节,共占40字节。
32位下,t1占1字节,后面填充3字节,t2中s1占1个字节,后面填充3个字节,t2中s2占8个字节,t2中s3占1个字节,后面填充3个字节,t3占8个字节,共占24字节。

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2021-08-09 10:03:37  更:2021-08-09 10:04:51 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/9 12:32:58-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码