结构体联合体sizeof内存求值 - 对齐数

news2024/11/28 2:35:00

讲解下struct和union的内存求值和对齐
以题目讲解

结构体联合体sizeof内存求值 - 对齐数

  • 不同位数下类型字节大小
  • 内存对齐规则
  • struct 内存对齐求值
  • 嵌套struct内存对齐求值
  • union的内存大小求值
    • union大小计算准则
  • struct嵌套union内存对齐求值

不同位数下类型字节大小

一定要搞清楚编辑器,一般编辑器中的类型字节如图:

类型16位平台32位平台64位平台
char1个字节1个字节1个字节
short2个字节2个字节2个字节
int2个字节4个字节4个字节
unsigned int2个字节4个字节4个字节
float4个字节4个字节4个字节
double8个字节8个字节8个字节
long4个字节4个字节8个字节
long long8个字节8个字节8个字节
unsigned long4个字节4个字节8个字节
指针2个字节4个字节8个字节

一般我使用的是64位的编译器,下面来看看对齐规则

 

内存对齐规则

规则

  • 结构体的第一个成员直接对齐到相对于结构体变量起始位置为0处偏移。
  • 从第二个成员开始,要对齐到某个【对齐数】的整数倍的偏移处。
  • 结构体的总大小,必须是最大对齐数的整数倍。每个结构体成员都有一个对齐数,其中最大的对齐数就是最大对齐数
  • 如果嵌套了结构体的情况。嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

 

struct 内存对齐求值

  • 举例:struct内存求值
#include <stdio.h>
#pragma pack(16)
struct BBB {
    long num;
    char ha;
    short ba[5];
}b;

int main() {
    printf("%d\n", sizeof(b.num));//8
    printf("%d\n", sizeof(b.ha)); //1
    printf("%d\n", sizeof(b.ba)); //10 ,short大小是2
    //最大对齐数是8

    printf("%d\n", sizeof(BBB));
    return 0;
}

//这里ba数组的最大对齐数是2,因为short大小2小于定义的对齐数16

//sizeof(BBB)=8+1+1+(2*5)=20,这里的1是为了让ba数组对齐到2的倍数
//但是对齐规则里面有个结构体的总大小,必须是最大对齐数的整数倍
//这里最大对齐数是8,也就是结果需要是8的倍数,最终等于sizeof(BBB)=24

在这里插入图片描述

 

嵌套struct内存对齐求值

  • 如果有嵌套结构体呢 :
#include <stdio.h>
#pragma pack(16)
struct BBB {
    long num;
    char ha;
    short ba[5];
    struct BBB2
    {
        int s; //4
        int ba2[5]; //20 
        char ha2[2]; //2
    }b2;  //4+20+2=26。对齐=4的倍数=28 
}b;

int main() {
    printf("%d\n", sizeof(b.num));//8
    printf("%d\n", sizeof(b.ha)); //1
    printf("%d\n", sizeof(b.ba)); //10 ,short大小是2
    printf("%d\n",sizeof(b.b2));//28,见上面
    //最大对齐数是8

    printf("%d\n", sizeof(BBB));
    return 0;
}
//sizeof(BBB)=8+1+1+(2*5)=20,后面嵌套的BBB2最大对齐数是4,对齐大小是28,所以从4的倍数出发,这里是20开始,正好,sizeof(BBB)=20+28=48,正好是8的倍数

 

union的内存大小求值

解释下union的内存大小求值

union大小计算准则

1、至少要容纳最大的成员变量
2、必须是所有成员变量类型大小的整数倍 —— 记住是成员变量类型 char c[7]算 1

  • 举例:求sizeof(union)
#include<stdio.h>
 
//联合体
union u2  
{
    char a;  //1
    int b; //4
    short c; //2
    double d; //8
    int e[5]; //20
}U3;
 
//主函数
int main(){ 
    printf("%d\n",sizeof(U3));//输出24
    return 0;
}

 

struct嵌套union内存对齐求值

#include <stdio.h>
#pragma pack(16)
struct BBB {
    int num;//4
    char ch; //1
    char pa[3]; //3
    union {
        int a; //4
        float b; //4
    } myUnion;//这个union内存大小等于4
}b;

int main() {
    printf("%d\n", sizeof(b));
    //4+1+3+4=12 ; 到char pa[3]时候这时候正好到地址8,然后union的内存是4,对齐数,要求是它的整数倍所以正好从8开始,最终结果12。满足是对齐数4,1,4的倍数
    return 0;
}

 

其他内容见专栏的结构体和联合体的文章
如果有啥补充的后续更新

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/423420.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【机器学习】P18 反向传播(导数、微积分、链式法则、前向传播、后向传播流程、神经网络)

反向传播反向传播反向传播中的数学导数与python链式法则简单神经网络处理流程从而理解反向传播神经网络与前向传播神经网络与反向传播反向传播 反向传播&#xff08;back propagation&#xff09;是一种用于训练神经网络的算法&#xff0c;其作用是计算神经网络中每个参数对损…

【Java虚拟机】JVM核心基础和常见参数实战

1.新版JVM内存组成部分和堆空间分布 JVM内存的5大组成&#xff08;基于JDK8的HotSpot虚拟机&#xff0c;不同虚拟机不同版本会有不一样&#xff09; 名称作用特点程序计数器也叫PC寄存器&#xff0c;用于记录当前线程执行的字节码指令位置&#xff0c;以便线程在恢复执行时能…

常见的DNS攻击与相应的防御措施

DNS查询通常都是基于UDP的&#xff0c;这就导致了在查询过程中验证机制的缺失&#xff0c;黑客很容易利用该漏洞进行分析。DNS服务可能面临如下DNS攻击风险&#xff1a; 黑客伪造客户端源IP地址发送大量的DNS请求报文&#xff0c;造成DNS request flood攻击。 黑客伪造成授权服…

MongoDB实现---存储机制

储存 GridFS机制 GridFS&#xff1a;将大文件分隔成多个小文档存放&#xff0c;这样我们能够有效的保存大文档&#xff0c;而且解决了BSON对象有限制的问题&#xff1b;通过两个集合实现&#xff1a;两个集合分别存储存储实际数据和存储文件的元数据&#xff1a; 元数据文件&…

一篇文章搞定《动手学深度学习》-(李沐)PyTorch版本的所有内容

目录 目录 简介 阅读指南 1. 深度学习简介 2. 预备知识 3. 深度学习基础 4. 深度学习计算 5. 卷积神经网络 6. 循环神经网络 7. 优化算法 8. 计算性能 9. 计算机视觉 10. 自然语言处理 环境 参考&#xff08;大家可以在这里下载代码&#xff09; 原书地址&#…

四结(4.13)多线程学习

今天又进行了一次学长授课&#xff0c;关于MySQL和JDBC本来学了增删查改操作&#xff0c;用IDEA也可以操作数据库&#xff0c;今天讲了一些数据库的规范&#xff08;三大范式&#xff09;、以及er图。了解了一下项目。 项目要分为客户端和服务端&#xff08;C/S&#xff09;来写…

vue面试题2023

1.$route和$router的区别? routes : 数组。 路由匹配规则 router &#xff1a; 对象。 路由对象 $router &#xff1a; 对象。 用于跳转路由 和 传递参数 $route &#xff1a;对象。 用于接收路由跳转参数 1.Vue的生命周期方法有哪些&#xff1f; - beforeCreate 初始化实…

科技云报道:“云减碳”成趋势,如何用“计算”帮助企业碳减排?

科技云报道原创。 将数据中心“丢进”水里、“扔进”山里&#xff0c;使用风能、太阳能等清洁能源为数据中心供电……这些都是通过物理方法为数据中心减碳。 数据中心的重要工作在于计算&#xff0c;计算导致了能源消耗&#xff0c;使其成为耗能大户&#xff0c;而通过云计算…

基于imx8m plus开发板全体系开发教程1:Windows/Linux 开发环境配置(连载中)

前言&#xff1a; i.MX8M Plus 开发板是一款拥有 4 个 Cortex-A53 核心&#xff0c;运行频率 1.8GHz;1 个 Cortex-M7 核心&#xff0c;运行频率 800MHz;此外还集成了一个 2.3 TOPS 的 NPU&#xff0c;大大加速机器学习推理。 全文所使用的开发平台均为与NXP官方合作的FS-IMX8…

Terraform 系列-什么是 IaC?

系列文章 &#x1f449; Terraform 系列文章 前言 聊到 Terraform, 必然绕不开 IaC 这个概念&#xff1f;那么&#xff0c;什么是 IaC? &#x1f914; 基本概念 基础架构即代码 (Infrastructure as Code, IaC) 是指通过代码而不是手动流程/控制台点击来管理和配置基础架构…

互联网+制造业:图扑数字孪生智慧工厂车间生产线

前言 随着信息技术、自动化技术和人工智能等技术的快速发展和应用&#xff0c;智能制造已成为全球制造业发展的主流趋势。智能制造是将智能化、自动化、数字化和网络化等技术手段运用到制造过程中&#xff0c;使生产过程具有高度智能化、自动化和数字化的特点&#xff0c;进而…

Linux安装宝塔,并实现公网远程登录宝塔面板【内网穿透】

文章目录前言1. 安装宝塔2. 安装cpolar内网穿透3. 远程访问宝塔4. 固定http地址5. 配置二级子域名6. 测试访问二级子域名转发自CSDN远程穿透的文章&#xff1a;Linux安装宝塔&#xff0c;并实现公网远程登录宝塔面板【内网穿透】 前言 宝塔面板作为建站运维工具&#xff0c;它…

网络编程2(套接字编程)

套接字编程UDP协议通信&#xff1a;TCP通信&#xff1a;套接字编程&#xff1a;如何编写一个网络通信程序 1.网络通信的数据中都会包含一个完整的五元组&#xff1a; sip&#xff0c;sport&#xff0c;dip&#xff0c;dport&#xff0c;protocol&#xff08;源IP&#xff0c;源…

计算机组成原理——第三章存储系统(上)

提示&#xff1a;吾与春风皆过客&#xff0c;君携秋水揽星河 文章目录前言3.1 存储系统基本概念3.2.1 主存储器的基本组成3.2.2 SRAM DRAM\3.2.3 只读存储器ROM3.3.1 主存储器与CPU的连接3.3.2 双端口RAM和多模块存储器前言 提示&#xff1a;以下是本篇文章正文内容&#xff0c…

带你理解运算放大器

复习一下电子设计基本元器件&#xff0c;运算放大器 ...... 矜辰所致目录前言一、运放基本说明1.1 基本认识1.2 运放中的电流1.3 运放工作特性二、负反馈2.1 什么是负反馈&#xff1f;2.2 为什么要引入负反馈&#xff1f;负反馈电路分析2.3 正反馈三、提一下虚短与虚断结语前…

MAX14808 八通道3级电平 数字脉冲发生器

MAX14808八通道3级电平 高压(HV) 脉冲发生器&#xff0c;利用低压控制逻辑输入产生高频、高压双极性脉冲(高达105V) &#xff0c;用于驱动超声系统的压电传感器&#xff0c;MAX14808有八个集成的发送/接收(T/R)开关。 应用 超声医疗成像工业探伤检测压电驱动器测试设备 芯片…

RocketMQ 是是如何管理消费进度的?又是如何保证消息成功消费的?

RocketMQ 消费者保障 作者: 博学谷狂野架构师GitHub&#xff1a;GitHub 地址 &#xff08;有我精心准备的 130 本电子书 PDF&#xff09;只分享干货、不吹水&#xff0c;让我们一起加油&#xff01;&#x1f604; 消息确认机制 consumer 的每个实例是靠队列分配来决定如何消费消…

五、MyBatis各种查询功能

MyBatis的各种查询功能 如果查询出的数据只有一条&#xff0c;可以通过 实体类对象接收List集合接收Map集合接收 如果查询出的数据有多条&#xff0c;一定不能用实体对象接收&#xff0c;会抛TooManyResultsException&#xff0c;可以通过 实体类类型的List集合接收Map类型的L…

Python爬虫自动化从入门到精通第10天(Scrapy框架的基本使用)

Scrapy框架的基本使用Scrapy框架简介Scrapy框架的运作流程安装Scrapy框架Scrapy框架的基本操作Scrapy常用命令Scrapy框架简介 Scrapy框架主要包含以下组件&#xff1a; Scrapy Engine(引擎)&#xff1a;负责Spiders、Item Pipeline、Downloader、Scheduler之间的通信&#xf…

手把手教你安装Visual Studio 2019(史上最全)

前言: 本文是以Visual Studio Community 2019为例子,介绍如何在微软官网下载Visual Studio Community 2019并安装.net桌面开发程序环境(主要是winform开发环境)。 下载请点击这里Visual Studio Community 2019下载,然后点击下图的箭头的DownLoad下载,要注意的是下载时要…