如何计算一个结构体的大小?(C语言)

news2024/11/20 13:34:04

文章目录

  • 写在前面
  • 1. 结构体的内存对齐
  • 2. 结构体大小的计算方式(四步法)
  • 3. 修改默认对齐数
  • 4. 内存对齐的意义
  • 5. 结构体设计技巧

写在前面

我们知道C语言中各种内置类型定义的变量都是有大小的,比如 int 类型的变量占4个字节,而像我们自定义类型的变量(结构体变量)大小又是多少呢?是简单的将每个成员变量的大小相加吗?带着疑问我们来探究一下结构体的大小到底是如何进行计算的。

1. 结构体的内存对齐

要想正确计算结构体的大小,首先要知道结构体内存对齐的规则。
结构体的内存对齐规则如下:

  • 第一个成员在与结构体变量偏移量为0的地址处。
  • 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
  • 对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。VS中默认的值为8。
  • 结构体总大小为最大对齐数(每个成员变量都有一个对齐数)的整数倍。
  • 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整
    体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

对齐偏移:每个数据类型都有一个对齐偏移量,表示从结构体的起始位置到该数据类型的首个有效字节的偏移量。

2. 结构体大小的计算方式(四步法)

上面我们了解了结构体内存对齐的规则以后,下面我们通过一个例子在vs2013这个平台来探究一下结构体的大小是如何计算的?

struct S1
{
	char c1;
	int i;
	char c2;
};

第一步:结构体的第一个成员放在结构体变量偏移量为0的地址处。c1是结构体的第一个成员变量,其类型是char类型,占一个字节。
在这里插入图片描述
第二步:依次写出结构体成员变量的对齐数。

  • 编译器默认的一个对齐数与该成员大小的较小值,VS中默认的对齐数为8。
    在这里插入图片描述
    第三步:将剩余成员变量依次对齐到该成员变量对齐数的整数倍的地址处。
    在这里插入图片描述
    第四步:计算结构体的大小。
  • 结构体总大小为最大对齐数的整数倍。
    此时结构体的最大对齐数是4,成员变量占用了9个字节,不是4的整数倍,继续往后浪费3个字节,最后结构体的大小为12个字节。
    在这里插入图片描述
    我们在vs平台上验证一下我们分析的结果:
    在这里插入图片描述

3. 修改默认对齐数

一些编译器允许使用预处理指令来修改默认对齐方式。例如,可以使用#pragma pack()指令来指定对齐方式。我们需要将默认对齐数修改为多少,在()里面填入多少即可。以下是一个示例:

#pragma pack(1) // 将默认对齐方式设置为1字节
struct MyStruct 
{
    int a;
    double b;
};
#pragma pack() // 恢复默认对齐方式

有了该预处理指令,我们可以根据我们的需求,设置相应的默认对齐数。

4. 内存对齐的意义

  1. 平台原因(移植原因):
    不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。
  2. 数据结构(尤其是栈)应该尽可能地在自然边界上对齐。
    原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要一次访问。

总之:结构体的内存对齐是一种优化技术,是一种拿空间来换取时间的做法

5. 结构体设计技巧

在设计结构体的时候,我们既要满足对齐,又要节省空间,我们需要如何设计结构体呢?
当在我们设计结构体的时候,如果结构体成员的顺序设计得不合理的话,是有可能造成内存浪费的。如下面这段代码:

#include <stdio.h>
struct S1
{
	char c1;
	int i;
	char c2;
};
struct S2
{
	char c1;
	char c2;
	int i;
};

int main()
{
	printf("struct S1 = %d, struct S2 = %d,", sizeof(struct S1), sizeof(struct S2));
	return 0;
}

上面两个结构体除了成员变量的顺序不同,并没有其他不同,而我们在按照计算结构体大小的规则来计算S1 和 S2的大小时,S1的大小为12个字节, S2的大小为8个字节。
在这里插入图片描述
在这里插入图片描述

因此,结构体在设计时,我们要尽可能的将占用空间小的成员集中在一起,以避免造成不必要的空间浪费。

至此,本片文章就结束了,若本篇内容对您有所帮助,请三连点赞,关注,收藏支持下。
创作不易,白嫖不好,各位的支持和认可,就是我创作的最大动力,我们下篇文章见!
如果本篇博客有任何错误,请批评指教,不胜感激 !
在这里插入图片描述

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

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

相关文章

对一个变速器原理的分析

背景 原本是朋友在调试一个看起来比较新的变速器驱动&#xff0c;整体来说支持两种变速模式&#xff0c;一种是进程级&#xff0c;这种用了HOOK&#xff0c;中规中矩的实现&#xff0c;原理网上都有。另一种是”系统级内核全局变速“&#xff0c;这个模式初步看了下有些特殊&a…

猫头虎带您了解CSDN1024城市开发者大会分会场报名指南(文末送30元优惠券)

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

全链路压测:保障系统稳定性与性能的关键措施

随着互联网应用规模的不断扩大和用户对系统性能要求的提高&#xff0c;全链路压测成为保障系统稳定性和性能的关键环节。本文将介绍全链路压测的概念、重要性以及实施全链路压测的步骤和最佳实践&#xff0c;以帮助读者更好地理解和应用全链路压测技术。 一、全链路压测的概念与…

客服支持Chatbot提供即时回答,改善用户体验

大家在网上冲浪了那么久&#xff0c;一定对于客户支持Chatbot都有所了解。客户支持Chatbot就像真人客服一样&#xff0c;可以与人进行简单的对话&#xff0c;并针对人们的需求给出相应的回答。虽然有时候得到的答案并不怎么靠谱吧&#xff0c;但是总的还是比较节省人工的&#…

docker概念

docker 容器&#xff1a;就是提供在多台主机上运行的应用程序相同的运行环境。 docker的概念 是开源的容器&#xff0c;是由Go语言开发的&#xff0c;是容器里面运用的工具&#xff0c;他是一个轻量级的虚拟机&#xff0c;可以利用docker在多台主机上创建与运行容器。 docke…

矩阵剪辑系统源码----pc/手机端双开发

剪辑系统&#xff0c;剪辑矩阵系统&#xff0c;剪辑矩阵系统主要是针对抖音、快手、bili平台的一个工具&#xff0c;今天就来给大家交流一下这 个产品的主要功能以及构成。剪辑矩阵系统&#xff0c;矩阵剪辑系统源码-这产品主要功能就是一个视频剪辑功能&#xff0c;这个视频剪…

深入解析:探索Nginx与Feign交锋的背后故事 - 如何优雅解决微服务通信中的`301 Moved Permanently`之谜!

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…

2023年中国数据存储市场现状及发展前景预测分析

中商情报网讯&#xff1a;当前&#xff0c;新一代信息技术快速发展推动信息产业发生了重大变革&#xff0c;数据存储行业将很快成为信息领域一个重要的产业分支。生成式人工智能催生算力需求&#xff0c;各种新兴应用场景对数据存储的容量、效率、流动性和安全性等方面提出了更…

快速入门C++

W...Y的主页&#x1f60a; 代码仓库分享&#x1f495; &#x1f354;前言&#xff1a; 我们学习了C语言&#xff0c;有了C语言的底子就更容易学习C&#xff0c;今天让我们认识一下C&#xff0c;并了解分析一下C。 目录 什么是C 为什么会出现C C的发展史 C与C语言的区别 …

漫画:大模型用于腾讯广告,难在哪?

&#xff08;一&#xff09;关键词&#xff1a;三大套路 大模型火了&#xff0c;大模型的套路也火了。 套路一&#xff1a; 但凡有点科技含量的公司&#xff0c; 没个大模型都对不起“市值”和“估值”。 面子谁不要&#xff1f; 那用开源。 套路二&#xff1a; 说早有布局&…

代码随想录Day16 LeetCode T654 最大二叉树 T617 合并二叉树 T700 二叉搜索树中的搜索

本文思路和更详细的解析来自于:代码随想录 (programmercarl.com)​​​​​​ LeetCode T654 最大二叉树 题目链接:654. 最大二叉树 - 力扣&#xff08;LeetCode&#xff09; 题目思路: 这题和昨天的题目很像,我们仍然需要构造一棵二叉树,我们仍然使用递归来完成,以下我们开始…

vue原生实现element上传多张图片浏览删除

vue原生实现element上传多张图片浏览删除 <div class"updata-component" style"width:100%;"><div class"demo-upload-box clearfix"><div class"demo-upload-image-box" v-if"imageUrlArr && imageUrlAr…

使用 Eziriz .NET Reactor 对c#程序加密

我目前测试过好几个c#加密软件。效果很多时候是加密后程序执行错误&#xff0c;或者字段找不到的现象 遇到这个加密软件用了一段时间都很正常&#xff0c;分享一下使用流程 破解版本自行百度。有钱的支持正版&#xff0c;我用的是 Eziriz .NET Reactor 6.8.0 第一步 安装 Ezi…

内存操作函数(memcpy、memmove、memset、memcmp)---- C语言

文章目录 摘要1. memcpy1.1 函数介绍1.2 模拟实现 2. memmove2.1 函数介绍2.2 模拟实现 3. memset3.1 函数介绍 4. memcmp4.1 函数介绍 摘要 本篇文章介绍了C语言中常用的内存操作函数&#xff0c;包括 memcpy、memmove、memset和memcpy。这些函数用于处理内存数据的复制、移动…

新鲜速递:Spring Cloud Alibaba环境在Spring Boot 3时代的快速搭建

了解 首先&#xff0c;Spring Cloud Alibaba使用的是Nacos作为服务注册和服务发现的中间件。 能力在提供者那里&#xff0c;而消费者只需知道提供者提供哪些服务&#xff0c;而无需关心提供者在哪里&#xff0c;实际调用过程如下图 准备工作 1、需要下载并安装Nacos最新版…

计算机丢失msvcr120.dll解决办法,快速解决的力量文件丢失

关于计算机丢失msvcr120.dll应该很多朋友都遇到过&#xff0c;本篇文章将和大家探讨一下关于计算机丢失msvcr120.dll解决办法。同时想和大叫一起了解一下msvcr120.dll文件到底有什么作用&#xff0c;是不是必须将其恢复。 一.msvcr120.dll的作用 msvcr120.dll文件时电脑中的一…

从 0 到 1 ,手把手教你编写《消息队列》项目(Java实现) —— 编写服务器

文章目录 一、自定义应用层协议请求与响应channel 二、自定义请求格式三、自定义响应格式四、服务器代码编写 一、自定义应用层协议 咱们这里的客户端与服务器的通信是基于TCP协议实现的. 当前要交互的 Message,以及调用各种API的请求,其实都是二进制数据. 因此咱们要自定义…

使用香橙派并基于Linux实现最终版智能垃圾桶项目 --- 上

硬件接线 & 最终实现图 目录 项目需求 需求1&#xff0c;2&#xff0c;3 --- 蜂鸣器&#xff0c;舵机&#xff0c;测距传感器的配合使用 实现思路&#xff1a; 代码展示&#xff1a; v1.c&#xff1a; 需求4 --- socket服务器实现远程通讯控制的实现 代码展示&#…

电子科大软件系统架构设计——系统架构设计

文章目录 系统架构设计系统设计概述系统设计定义系统设计过程系统设计活动系统设计基本方法系统设计原则系统设计方法分类面向对象系统分析与设计建模过程 系统架构基础系统架构定义系统架构设计定义系统架构作用系统架构类型系统总体架构系统拓扑架构系统拓扑架构类型系统拓扑…

网络原理~初识

今天开始介绍的是网络&#xff0c;这是最核心最重要的板块之一~ 目录 网络互连 局域网 LAN 广域网WAN 网络通信基础 IP地址 端口号 协议 发送方的工作 应用层 传输层 网络层 数据链路层 物理层 接收方的工作 网络互连 随着时代的发展&#xff0c;越来越需要计算…