C语言结构体:内存布局与对齐

目录

C语言结构体:内存布局与对齐

一、 结构体类型定义

二、 结构体变量的创建和初始化

三、 内存对齐 (Memory Alignment)

对齐规则:

举例说明 (假设 int 为 4 字节,char 为 1 字节,double 为 8 字节):

四、 影响和优化

总结:


C语言结构体:内存布局与对齐

        C语言结构体 (struct) 是一种用户自定义的数据类型,它允许将不同类型的数据组合成一个整体。理解结构体的内存布局,特别是内存对齐,对于编写高效、可移植的代码至关重要。

一、 结构体类型定义

结构体类型的定义使用 struct 关键字,其基本语法如下:

struct 结构体名 
{数据类型 成员名1;数据类型 成员名2;...数据类型 成员名n;
};

例如:

struct Student 
{char name[20];int age;float score;
};

        这定义了一个名为 Student 的结构体类型,包含三个成员:姓名(字符数组)、年龄(整数)和分数(浮点数)。

二、 结构体变量的创建和初始化

创建结构体变量的方法有两种:

  1. 声明时初始化:

    struct Student student1 = {"Alice", 18, 85.5};
    

    声明后初始化:

    struct Student student2;
    student2.name = "Bob";
    student2.age = 20;
    student2.score = 92.0;
    

三、 内存对齐 (Memory Alignment)

        结构体成员在内存中并非紧密排列,而是按照一定的规则进行对齐。 对齐的目的是为了提高访问效率。 处理器通常更有效地访问特定对齐方式的数据(例如,32位整数通常需要4字节对齐)。

对齐规则:

  • 成员对齐: 每个成员的起始地址必须是其自身大小的整数倍。 例如,int 类型通常是 4 字节对齐,double 类型通常是 8 字节对齐。

  • 结构体对齐: 结构体的总大小通常是其最大成员大小的整数倍。

  • 编译器控制: 编译器通常允许通过编译选项控制对齐方式。

举例说明 (假设 int 为 4 字节,char 为 1 字节,double 为 8 字节):

例子1:

struct Example1 
{char a;int b;double c;
};

 内存布局图示:

+-------+-------+-------+-------+-------+-------+-------+-------+
|   a   |       |       |   b   |       |       |       |   c   |
+-------+-------+-------+-------+-------+-------+-------+-------+0     1     2     3     4     5     6     7     8     9    10   11   12   13  14  15

    a 占用 1 字节,b 需要 4 字节对齐,所以 b 从地址 4 开始。c 需要 8 字节对齐,所以 c 从地址 8 开始。总大小为 16 字节 (8的倍数)。

例子2:

struct Example2 
{int b;char a;double c;
};

内存布局图示:

+-------+-------+-------+-------+-------+-------+-------+-------+
|   b   |       |       |   a   |       |       |       |   c   |
+-------+-------+-------+-------+-------+-------+-------+-------+0     1     2     3     4     5     6     7     8     9    10   11   12   13  14  15

    b 占用 4 字节,a 占用 1 字节,c 需要 8 字节对齐,所以 c 从地址 8 开始。总大小为 16 字节 (8的倍数)。

例子3 (添加填充):

struct Example3 
{char a;int b;char d;
};

内存布局图示:

+-------+-------+-------+-------+-------+
|   a   |  pad  |  pad  |  pad  |   b   |
+-------+-------+-------+-------+-------+
|   d   |       |       |       |       |
+-------+-------+-------+-------+-------+0     1     2     3     4     5     6     7

    a 占用 1 字节,b 需要 4 字节对齐,所以插入 3 字节填充 (pad)。d 占用 1 字节,因为b占用了4个字节,d不需要额外填充,总大小为 8 字节 (4的倍数)。

四、 影响和优化

        内存对齐会影响结构体的大小和内存使用效率。 不必要的填充会浪费内存空间。 可以通过调整成员顺序来减少填充。 在需要节省内存空间的场合,可以考虑使用编译器选项来控制对齐方式,但要权衡效率和可移植性。

总结:

        理解结构体的内存布局和对齐规则对于编写高效的 C 代码至关重要。 通过合理的设计和安排结构体成员,可以减少内存浪费,提高程序性能。 学习使用编译器选项来控制对齐方式也能帮助优化内存使用。

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

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

相关文章

jenkins离线安装插件

Jenkins 在线安装插件失败 报错: Caused: java.io.IOException: Failed to load https://updates.jenkins.io/download/plugins/login-theme/244.vd67c77f0c4c8/login-theme.hpi to /var/jenkins_home/plugins/login-theme.jpi.tmpat hudson.model.UpdateCenter$Up…

人工智能学习——前言

一、概论理解 首先何为人工智能?简单一句人话就是:人工操纵搭建出来的智能学习模型 那我们要用它干什么?简单一句话就是:我们给出指令 ——> 得到想要的结果 最简单的生活例子来看:就好比小狗,我们让它…

C++11——异常

1.异常概念 异常是一种处理错误的方式,当一个函数发现自己无法处理的错误时就会抛出异常,让函数的调用者处理这个错误 throw:当出现问题时,程序会抛出一个异常,通过 throw 来完成catch:catch 关键字捕获异…

腾讯:将LLM排序能力迁移至BERT

📖标题:Best Practices for Distilling Large Language Models into BERT for Web Search Ranking 🌐来源:arXiv, 2411.04539 🌟摘要 🔸最近的研究强调了大型语言模型(LLM)作为零样…

unity 打包WebGL打开后Input无法输入中文,在手机端无法调用输入法(使用WebGLInput)

成果展示 1、只是在电脑上运行时 使用TexMeshPro-InputField组件就可以输入中文了 2.不仅在电脑上运行,还需要在移动端运行 这个时候就需要使用WebGLInput插件,连接里有测试demo 1、下载后把WebGLSupport.unitypackage 导入到工程里 2、给input添加两…

服务器上部署并启动 Go 语言框架 **GoZero** 的项目

要在服务器上部署并启动 Go 语言框架 **GoZero** 的项目,下面是一步步的操作指南: ### 1. 安装 Go 语言环境 首先,确保你的服务器上已安装 Go 语言。如果还没有安装,可以通过以下步骤进行安装: #### 1.1 安装 Go 语…

如何通过统一权限管理打破异构系统的安全屏障

企业在运营过程中面临着众多异构系统的整合挑战,这些异构系统由于其不同的技术架构、数据格式和安全机制等,给信息管理带来了诸多挑战。其中,“信息孤岛”问题尤为突出,而异构环境下的统一授权管理系统则成为解决这一问题的关键。…

【IDEA】插件篇(JClassLib)

一、JClassLib 1、概述 jclasslib 字节码编辑器是一个可视化已编译Java类文件和包含的字节码的工具。 项目地址:https://github.com/ingokegel/jclasslib 其他反编译工具:javap、arthas 2、安装 IntelliJ IDEA -> Preferences -> Plugins&am…

机器学习阶段学习Day31

KNN分类算法 KNN算法原理 根据K个邻居样本来判断当前样本属于哪个类别:K个最相似邻居中大多数所属类别即为当前样本的类别。但是对于数据量巨大或者高纬度的数据样本不太合适,数据量大的数据样本需要进行大量计算,而高纬度数据计算距离不具…

深入理解前端路由

目录 前言1. 什么是路由2. Vue Router 的基础2.1 安装 Vue Router2.2 创建路由器2.3 在应用中使用 Vue Router 3. 路由切换与编程式导航3.1 声明式导航3.2 编程式导航 4. 子路由:结构化的路由管理4.1 子路由的定义4.2 子路由的渲染 5. 高级用法:路由守卫…

【UGUI】Unity 游戏开发:背包系统初始化克隆道具

在游戏开发中,背包系统是一个非常常见的功能模块。它允许玩家收集、管理和使用各种道具。今天,我们将通过一个简单的示例来学习如何在 Unity 中初始化一个背包系统。我们将使用 Unity 2021.3.7 版本,并结合 C# 脚本来实现这一功能。 1. 场景…

grafana+prometheus+windows_exporter实现windows进程资源占用的监控

grafanaprometheuswindows_exporter实现windows进程资源占用的监控TOC 一、 管理端搭建,采用windows版本的grafanaprometheus 管理端安装部署不做本文终端,简单讲解一下,此处采用msi的grafana安装包,和免安装版本的prometheus 1…

ElementUI之给el-table实现搜索功能

1&#xff0c;有一个表格 <el-table:data"tableData"borderstyle"width: 100%"><el-table-columnprop"date"label"日期"width"180"></el-table-column><el-table-columnprop"name"label&quo…

Chrome 浏览器 131 版本开发者工具(DevTools)更新内容

Chrome 浏览器 131 版本开发者工具&#xff08;DevTools&#xff09;更新内容 一、使用 Gemini 调试 CSS Chrome DevTools 现在推出了一个新的实验性 AI 辅助面板&#xff0c;可以与 Gemini 聊天并获得帮助来调试 CSS。 在 Elements 面板中&#xff0c;右键点击一个元素并选…

Ubuntu20.04 Rk3588 交叉编译ffmpeg7.0

firefly 公司出的rk3588的设备&#xff0c;其中已经安装了gcc 交叉编译工具&#xff0c;系统版本是Ubuntu20.04。 使用Ubuntu20.04 交叉编译ffmpeg_ubuntu下配置ffmpeg交叉编译器为arm-linux-gnueabihf-gcc-CSDN博客文章浏览阅读541次。ubuntu20.04 交叉编译ffmpeg_ubuntu下配…

蓝桥杯第22场小白入门赛2~5题

这场比赛开打第二题就理解错意思了&#xff0c;还以为只能用3个消除和5个消除其中一种呢&#xff0c;结果就是死活a不过去&#xff0c;第三题根本读不懂题意&#xff0c;这蓝桥杯的题面我只能说出的是一言难尽啊。。第四题写出来一点但是后来知道是错了&#xff0c;不会正解&am…

sagemaker中使用pytorch框架的DLC训练和部署cifar图像分类任务

参考资料 https://github.com/aws/amazon-sagemaker-examples/blob/main/sagemaker-python-sdk/pytorch_cnn_cifar10/pytorch_local_mode_cifar10.ipynbhttps://sagemaker.readthedocs.io/en/stable/frameworks/pytorch/using_pytorch.html 获取训练数据 # s3://zhaojiew-sa…

golang笔记8-函数

1. 基本函数 package mainimport "fmt"/*什么是函数&#xff1a;完成某一功能的程序指令的集合语法&#xff1a;func 函数名称(形参列表)(返回值类型列表){执行语句。。。返回值列表}注意事项&#xff1a;函数名&#xff1a;函数名首字母大写&#xff1a;可以被本包…

vite+vue3+ts编译vue组件后,编译产物中d.ts文件为空

一、前言 使用vue3vitets实现一个UI组件库&#xff0c;为了生成类型文件便于其他项目引用该组件库。根据推荐使用了vite-plugin-dts插件进行ts文件的生成 二、版本 组件版本vue ^3.5.12 vite ^5.4.10 vite-plugin-dts ^4.3.0 typescript ~5.6.2 三、问题描述 使用vitevi…

向量数据库FAISS之二:基础进阶版

基础 1.评价类型和距离 1.METRIC_L2 Faiss 使用了欧几里得 (L2) 距离的平方&#xff0c;避免了平方根。 这仍然与欧几里德距离一样单调&#xff0c;但如果需要精确距离&#xff0c;则需要结果的额外平方根。 2.METRIC_INNER_PRODUCT 这通常用于推荐系统中的最大内积搜索。…