如何计算:结构体内存的大小(在结构体的考察中占据非常重要的地位)

2023-11-03

在之前的文章中,笔者就结构体的简单定义,初始化,等内容,进行了简单描述!!但是,对于int  ,double ,float ,char 等类型都有自己的大小,但是,对于一个结构体,它的大小该如何计算呢???确实是一个疑问??这个也是不少老铁,在刚学结构体时候的最大煎熬!下面,笔者来带领大家熟悉一下,结构体大小的计算!!

在讲解之前,需要大家知道一下几点:

1.结构体的第一个成员,直接对齐到相对于结构体变量起始位置为0的偏移处!!

2.从第二个成员开始,要对齐到某个对齐数整数倍的偏移处!

对齐数:结构体成员自身大小和默认对齐数的较小值!

在VS中,默认的对齐数为:8

在Linus环境不设默认对齐数(对齐数是结构体成员的自身的大小)

3.结构体的总大小,必须是最大对齐数的倍数!!每个结构体成员都有一个对齐数,其中最大的对齐数就是最大对齐数!!

4.如果嵌套结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小:就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍

下面笔者用代码加解析的方法来演示一下:

#include <stdio.h>

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

int main()
{
	printf("%d\n", sizeof(struct s1));
	return 0;
}

上面定义了一个结构体,里面存放有:char c1;    int i;   char c2; (我们先注意一下,结构体里面的先后顺序) char 占一个字节,Int 占4个字节!但是对于运行结果:12个字节????什么鬼这是??

 不相信的各位老铁,可以在VS的x86环境下进行实现!读者可以自己进行验证!!

 对于结构体的仔细划分为:

 经过上面的笔者必须知道的部分:1,2,3,三点,我们可以有:

但是,笔者将上面的结构体的顺序,稍微改写一下:

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

请注意一下,先后顺序!!

对于这个代码,该结构体的大小,又是多少呢???想必,到此为止,各位老铁,不再是:1+1+4=6个字节了吧!!

请看这代码的运行结果:

 但是,这个结果是8,这个又是为什么呢??各位老铁,可以根据,前面的那个案列来分析一下:

 对于上面两个案列的简单讲解,想必大家也能理解了:如何来求结构体大小的方法!!

下面,笔者来带领大家,求一下:结构体成员,相对于起始位置的偏移量!!

offset是一个宏!!是用来计算:结构体成员相对于起始位置的偏移量的一个宏!

使用语法为:

offsetof(type ,member);

type 是指:哪个结构体类型! ,member 是指:成员名!!

下面笔者用代码加解析的方式来带领大家了解一下:


#include <stdio.h>
#include <stddef.h>

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

int main()
{
	printf("%d\n", offsetof(struct  s1 , c1));   //0
	printf("%d\n", offsetof(struct  s1, i));     //4
	printf("%d\n", offsetof(struct  s1, c2));    //8

	return 0;
}

上面代码的运行结果为:

 这个在,笔者的讲解过程:

 因此,结构体的总大小,必须是:最大对齐数的倍数

同理可得,我们也可以对

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

来进行同样的道理分析:


#include <stdio.h>
#include <stddef.h>

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

int main()
{
	printf("%d\n", offsetof(struct  s2, c1));   //0
	printf("%d\n", offsetof(struct  s2, c2));     //1
	printf("%d\n", offsetof(struct  s2, i));    //4

	return 0;
}

 想必现在,大家对于该结构体的大小,目前没有什么问题了吧!!

对于嵌套部分的结构体,我们一样可以用这样的方法来进行求解!!相信大家都是可以求出来的!!

经过上面的结构体对齐的方法讲解:想必大家也有着:为什么存在内存对齐??有着疑惑!!下面笔者来进行简单讲解一下:

1.平台原因

不是所有的硬件平台都能访问任意地址上的任意数据的,某些硬件平台只能在某些地址处,取某些特定类型的数据,否则,抛出硬件正常!

2.性能原因

数据结构(尤其是栈)应该尽可能地在自然边界上对齐,原因在于:为了访问未对其的内存,处理器需要做两次内存访问,而对齐的内存访问,仅需要访问一次!

总的来说:

结构体的内存对齐是拿空间换取时间的做法!

那么设计结构体的时候,我们既要满足对齐,又要节省空间,就要做到:

  让占用空间小的成员尽量集中在一起!!

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何计算:结构体内存的大小(在结构体的考察中占据非常重要的地位) 的相关文章

随机推荐

  • 对比openai,我更喜欢ppword的近期更新

    刚刚 23年8月17日 openai宣布收购Global Illumination Global Illumination简单说 就是人工智能落地公司 来帮chatGPT找落地场景 昨天 23年8月16日 宣布更新了内容审核的解决方案 号称
  • 机器学习算法 随机森林

    文章目录 一 概述 1 1 集成学习 1 2 决策树 1 3 随机森林 二 Sklearn中的随机森林 2 1 分类树API 2 2 参数 2 2 回归树API 2 2 1 重要参数 2 3 随机森林调参 三 总结 一 概述 1 1 集成学
  • unity渲染队列render quaue

    本文转载自http blog csdn net candycat1992 article details 37345251 本系列主要参考 Unity Shaders and Effects Cookbook 一书 感谢原书作者 同时会加上
  • shell中for循环变量常见使用场景

    shell中for循环变量常见使用场景 1 目的 在shell脚本for循环使用过程中经常出现非常规使用场景 如在awk的条件语句中 输出文本中变量后有字符等 这些场景中需要对for循环中的变量做处理 希望持续完善 2不同场景 2 1 变量
  • React配置webpack(一)

    一 安装 create react app npx create react app react webpack app cd react webpack app npm start 二 初始化项目 npm init y 三 安装所需包 w
  • Linux中Hadoop的安装与配置

    1 首先关闭虚拟机的防火墙 2 查看防火墙状态 3 然后修改主机名称 配置hosts vi etc hosts 前面是自己的主机IP地址 后面是想要修改的主机名称 修改完成保存后reboot重启即可修改完成 4 把Hadoop和jdk压缩包
  • 一文读懂迭代器(iterator)在vector中的用法

    首先写好头文件vector和string的头文件是 include
  • Linux中vim下方向键变成ABCD,backspace无法删除字符的解决办法

    在linux中安装完VIM后 发现在insert模式下 按下四个方向键在屏幕中会输出ABCD这样的字符 并且Backspace无法实现删除功能 虽然可以在normal模式下通过hjkl实现光标的移动 通过x和d实现删除功能 但是每次都要进行
  • 【Python编程】删除列表中具有连续重复项的元素

    删除列表中具有连续重复项的元素 输入 1 1 1 1 1 1 2 3 4 4 5 1 2 输出 1 2 3 4 5 1 2 方法1 循环遍历 a 1 1 1 1 1 1 2 3 4 4 5 1 2 i 0 while i lt len a
  • 如何成为一名AI人工智能算法工程师?

    https www toutiao com a6707050434688713227 经常有朋友私信问 如何学python呀 如何敲代码呀 如何进入AI行业呀 正好回头看看自己这一年走过的路 进行一次经验总结 来看看你距离成为一名AI工程师
  • 时序预测:MATLAB实现时间序列回归之Bootstrapped测试

    时序预测 MATLAB实现时间序列回归之Bootstrapped测试 时序预测是实际应用中非常重要的任务 它在金融 企业经营 气象预测等领域都有广泛的应用 而时间序列回归也是时序预测中最为基础和实用的方法之一 本文将通过MATLAB对时间序
  • 【QT实战】第一章 QT实现画板工具的制作

    作者主页 凉开水白菜 作者简介 共同学习 互相监督 热于分享 多加讨论 一起进步 专栏目录 零基础学QT 文章导航篇 专栏资料 https pan baidu com s 192A28BTIYFHmixRcQwmaHw 提取码 qtqt 点
  • c++ 学习之 构造函数的使用规则

    上规则 默认情况下 c 编译器至少给一个类添加三个函数 1 默认构造函数 无参 函数体为空 2 默认析构函数 无参 函数体为空 3 默认拷贝函数 对其属性进行值拷贝 构造函数调用规则 如果用户定义有参构造函数 c 不再提供默认无参构造函数
  • android自定义数字键盘

    前言 最近需要做一个自定义的数字键盘 开始使用了下系统自带的KeyBoardView 但是发现UI效果不是很理想 最后还是自己画一个自定义键盘 这样在UI方面更加方便 先看效果图吧 思路 1 键盘4行 3列的布局分为12个单元格 6条直线分
  • 【神经网络学习】鸢尾花分类的实现

    目录 1 问题 2 问题解决思路 3 神经网络理论准备 4 Tensor Flow编程基础 5 鸢尾花分类神经网络实现 1 问题 鸢尾花分为 狗尾草鸢尾 杂色鸢尾 弗吉尼亚鸢尾 通过测量 花萼长 花萼宽 花瓣长 花瓣宽 这四个参数得出鸢尾花
  • PCB的3D模型的一些工具

    stp转 step的工具 免费将 STP 转换为 STEP ImageToStl
  • Windows 修改 cmd 命令行窗口字符编码

    查看当前 cmd 命令行窗口字符编码 已经是UTF 8 如果要修改为UTF 8 打开注册表 WIN R输入 regedit 回车 找到 HKEY LOCAL MACHINE SOFTWARE Microsoft Command Proces
  • WMS仓储管理系统在各种行业中,都有哪些作用

    由计算机控制的仓库管理系统的目的是独立实现仓储管理各种功能 收货 在正确的地点存货 存货管理 订单处理 分拣和配送控制 WMS仓储管理系统将关注的焦点集中于对仓储执行的优化和有效管理 同时延伸到运输配送计划 和上下游供应商客户的信息交互 从
  • python PDB调试

    1 python m pdb py 从第一行开始pdb调试 2 断点设置 在某一行插入 import pdb pdb set trace 3 常用命令 n ext 下一步 s tep 进入函数 c ontinue 继续到下一个断点 l is
  • 如何计算:结构体内存的大小(在结构体的考察中占据非常重要的地位)

    在之前的文章中 笔者就结构体的简单定义 初始化 等内容 进行了简单描述 但是 对于int double float char 等类型都有自己的大小 但是 对于一个结构体 它的大小该如何计算呢 确实是一个疑问 这个也是不少老铁 在刚学结构体时