【C语言】结构体内存对齐机制详解

news2025/1/22 16:05:04

目录

    • 一、前言
    • 二、结构体内存对齐规则
    • 三、实例解析

一、前言

在讲解结构体内存对齐机制之前,我们先来看1个例子:

typedef struct
{
    char sex;       //  性别
    int id;         //  学号
    char name[20];  //  姓名
    float score;    //  成绩
    char addr[30];  //  地址
}STU;

int main(){
    STU student1;
    printf("%d\n",sizeof(student1));//  打印结构体变量所占内存长度
    return 0;
}

以上代码示例中定义了1个结构体student1,包含5个不同数据类型的成员,分别占用内存空间:
char sex:1 Byte
int id:4 Byte
char name[20]:20 Byte
float score:4 Byte
char addr[30]:30 Byte
根据结构体特性,结构体变量所占内存长度等于其各成员所占内存长度之和,因此这里打印的sizeof(student1)是否等于1+4+20+4+30=59呢?运行程序后结果如下:

size of student1: 64

为什么这里结构体变量student1所占内存长度是64而不是59呢?因为有结构体内存对齐机制的存在。这是很多新手程序猿很容易走进的一个误区,接下来我们一起来了解结构体对齐机制。

二、结构体内存对齐规则

  1. 结构体第一个成员的地址即为该结构体变量的地址。
  2. 结构体成员内存对齐时,其存放的内存单元大小为min{有效对齐值,指定对齐值}的最小整数倍。
    注意:
    自身对齐值: 结构体变量里每个成员自身所占内存大小
    指定对齐值: 使用宏定义#pragma pack(N) 其中N的值即为指定对齐值。N必须是2的幂次方,例如:1,2,4,8等,如果没有使用宏定义指定对齐值,则指定对齐值取决于操作系统位数,32位操作系统默认指定对齐值为4,64位操作系统默认指定对齐值为8
    有效对齐值: 有效对齐值为min{自身对齐值,指定对齐值}。
  3. 结构体总占用内存大小为min{成员最大自身对齐值,指定对齐值}的整数倍。

三、实例解析

以下示例代码均在64位Windows操作系统下运行
1、使用默认指定对齐值
使用文章前言的代码分析:

#include <stdio.h>

typedef struct
{
    char sex;       //  性别
    int id;         //  学号
    char name[20];  //  姓名
    float score;    //  成绩
    char addr[30];  //  地址
}STU;

int main(){
    STU student1;
    printf("size of student1: %d\n",sizeof(student1));    //  打印结构体变量所占内存长度
    return 0;
}
成员自身对齐值指定对齐值有效对齐值
sex18min{1,8}
id48min{4,8}
name[20]18min{1,8}
score48min{4,8}
addr[30]18min{1,8}

结构体总体对齐时,应按照成员自身对齐值的最大值的整数倍对齐,这里程序在没有宏定义指定默认对齐值的情况下,对齐值就应该是min{4,8},也就是4字节,这种情况下,该结构体每一个成员开辟的存储空间都为4字节。

成员实际占用内存大小系统开辟内存空间大小
sex14
id44
name[20]2020
score44
addr[30]3032

在这里插入图片描述

成员id、name[20]、score实际占用内存大小刚好是对齐值4的整数倍,而成员sex则需要开辟4字节空间,实际只占用1字节,剩余3字节未使用;成员addr[30]需要开辟32字节空间,实际使用30字节,剩余2字节未使用。因此打印结构体变量student1所占内存大小为64字节。

2、修改默认指定对齐值
在上述示例基础之上修改默认指定对齐值:

#include <stdio.h>
#pragma pack(1) //  指定默认对齐值为1
typedef struct
{
    char sex;       //  性别
    int id;         //  学号
    char name[20];  //  姓名
    float score;    //  成绩
    char addr[30];  //  地址
}STU;
#pragma pack()  //  取消修改对齐值
int main(){
    STU student1;
    printf("size of student1: %d\n",sizeof(student1));    //  打印结构体变量所占内存长度
    return 0;
}

此时程序输出结果为:

size of student1: 59

以上代码使用#pragma pack(1) 将默认指定对齐值修改为1,那么结构体成员将会按照1字节做内存对齐。

成员实际占用内存大小系统开辟内存空间大小
sex11
id44
name[20]2020
score44
addr[30]3030

此时打印结构体变量student1所占内存长度就为59。

如果将默认指定对齐值修改为2呢?

#include <stdio.h>
#pragma pack(2) //  指定默认对齐值为1
typedef struct
{
    char sex;       //  性别
    int id;         //  学号
    char name[20];  //  姓名
    float score;    //  成绩
    char addr[30];  //  地址
}STU;
#pragma pack()  //  取消修改对齐值
int main(){
    STU student1;
    printf("size of student1: %d\n",sizeof(student1));    //  打印结构体变量所占内存长度
    return 0;
}

程序输出结果:

size of student1: 60
成员实际占用内存大小系统开辟内存空间大小
sex12
id44
name[20]2020
score44
addr[30]3030

这个时候除了成员sex之外,其余成员的自身对齐数均是2的整数倍,因此成员sex需要根据对齐数2进行内存对齐,开辟2字节空间存储,但实际只使用1字节空间,最后打印结构体变量student1的所占内存长度为60。

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

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

相关文章

中秋特辑——3D动态礼盒贺卡(可监听鼠标移动)

前言 「作者主页」&#xff1a;雪碧有白泡泡 「个人网站」&#xff1a;雪碧的个人网站 「推荐专栏」&#xff1a; ★java一站式服务 ★ ★ React从入门到精通★ ★前端炫酷代码分享 ★ ★ 从0到英雄&#xff0c;vue成神之路★ ★ uniapp-从构建到提升★ ★ 从0到英雄&#xff…

华纳云:如何搭建Nginx服务器做到负载均衡

要搭建Nginx服务器实现负载均衡&#xff0c;您可以使用Nginx作为反向代理来分发客户端请求到多个后端服务器。以下是一个基本的步骤指南&#xff1a; 前提条件&#xff1a; 您需要一台安装有Nginx的服务器。您需要有多台后端服务器&#xff0c;这些服务器将处理客户端请求。 …

centos7 装机遇到的问题

centos7 U盘启动装机 设置完启动项后重启 在菜单界面选择install centos7 按e编辑启动项&#xff0c;修改成如下 --> 之所以这么改是u盘的LABEL超过长度了只能显示到x8这里&#xff0c;nomodeset 是disable 视频驱动比如gpu 开始安装后如果选择的硬盘没有多余的空间了会提…

TikTok的媒体革命:新闻业如何适应短视频时代?

在数字时代&#xff0c;媒体行业一直在不断演变和创新&#xff0c;以适应观众的变化需求和技术的发展。而在这个进化的过程中&#xff0c;短视频应用TikTok已经崭露头角&#xff0c;成为了一个重要的信息传播平台。 这篇文章将深入探讨TikTok如何引领了媒体的一场革命&#xf…

mininum_snap

位置 速度 加速度 角度 jerk 角速度 驱动力 snap 角加速度 推力的导数 凸优化算法 convex optimization 凸优化&#xff08;Convex Optimization&#xff09;是数学和计算机科学领域的一个重要分支&#xff0c;主要研究如何有效地解决凸优化问题。凸优化问题的主要目标是找…

pytest进阶之conftest.py

前言 前面几篇随笔基本上已经了解了pytest 命令使用&#xff0c;收集用例&#xff0c;finxture使用及作用范围&#xff0c;今天简单介绍一下conftest.py文件的作用和实际项目中如是使用此文件&#xff01; 实例场景 首先们思考这样一个问题&#xff1a;如果我们在编写测试用…

AIMS医院手术麻醉信息系统全套源码,自主版权,开箱即用

手术麻醉临床信息系统有着完善的临床业务功能&#xff0c;能够涵盖整个围术期的工作&#xff0c;能够采集、汇总、存储、处理、展现所有的临床诊疗资料。通过该系统的实施&#xff0c;能够规范麻醉科的工作流程&#xff0c;实现麻醉手术过程的信息数字化&#xff0c;自动生成麻…

如何无损压缩视频?这些技巧你一定用得到

在日常生活中&#xff0c;我们常常会遇到视频文件过大、手机或电脑存储空间不足的情况。这时候&#xff0c;我们就需要将这些视频文件的内存进行压缩&#xff0c;以节省空间。但是&#xff0c;一个一个地压缩视频文件显然是不现实的。那么&#xff0c;如何快速批量压缩视频呢&a…

【马蹄集】—— 数论专题:筛法

数论专题 目录 MT2213 质数率MT2214 元素共鸣MT2215 小码哥的喜欢数MT2216 数的自我MT2217 数字游戏 MT2213 质数率 难度&#xff1a;黄金    时间限制&#xff1a;1秒    占用内存&#xff1a;256M 题目描述 请求出 [ 1 , n ] \left[1,n\right] [1,n] 范围内质数占比率。…

【word技巧】如何限制word页眉,不被他人修改

我们设置了页眉内容之后&#xff0c;不想其他人修改自己的页眉内容&#xff0c;我们可以设置加密的&#xff0c;设置方法如下&#xff1a; 先将页眉设置好&#xff0c;退出页眉设置之后&#xff0c;我们选择布局功能&#xff0c;点击分隔符 – 连续 设置完之后页面分为上下两节…

基于vue3 的 Echarts图表展示(任务一:用柱状图展示消费额最高的省份)(操作全流程)(图文版)

目录 前言&#xff1a; 操作要求&#xff1a; 操作流程&#xff1a; 一.创建vue项目 1.在vscode上创建vue脚手架工程 二.配置运行环境 2.配置axios(用于访问接口) 和引入echarts包 3.引入需要用到的js包 三.开始实践做题(最后附有完整代码) 1.获取接口数据 2.数据处理 …

博格华纳高压发卡式电机解析

博格华纳的高压发卡式电机具有功率强大、坚固耐用和高性能等特点&#xff0c;采用紧凑型设计&#xff0c;优化的导体绕组结构缩短了电机的尺寸&#xff0c;使其便于在更小的空间内进行安装&#xff0c;并提高了常用区间的工作效率。此外&#xff0c;电机在设计上减少了重稀土元…

Spring Cloud Alibaba Nacos 2.2.3 (4) - 本地源码编译 调试

下载nacos nacos在GitHub上有下载地址&#xff1a;https://github.com/alibaba/nacos/releases&#xff0c;可以选择任意版本下载。 我下载的是2.2.3 版本 导入idea mvn 安装包 1&#xff0c;切换到Terminal ,并且使用command prompt模式 2&#xff0c;执行 mvn -Prelease…

Delaunay三角剖分算法

目录 一. 简介1.1 三角剖分1.2 Delaunay三角剖分 二. Delaunay三角剖分的相关理论2.1 Delaunay三角形和&#xff08;局部&#xff09;Delaunay边的概念2.2 Delaunay引理2.3 翻转边算法&#xff08;flip algorithm&#xff09;2.4 Delaunay三角剖分的最优性质 三. Delaunay三角剖…

缺口的大利润!伦敦银如何使用缺口交易

在伦敦银市场中&#xff0c;我们经常能够看见市场跳空形成缺口&#xff0c;其实&#xff0c;如果利用得当&#xff0c;我们在伦敦银投之中&#xff0c;这些缺口是能够为我们创造盈利机会的&#xff0c;那么下面我们就来讨论一下在伦敦银投之中如何认识这些跳空缺口&#xff0c;…

哪些远程桌面软件适合与团队共享屏幕和文件

远程桌面软件是一种方便团队协作和共享工作的工具。它们能够允许用户通过互联网连接到其他计算机&#xff0c;实现远程访问、共享屏幕和文件、以及协同工作。以下是一些适合与团队共享屏幕和文件的常用远程桌面软件。 1、RayLink RayLink是一款功能强大且易于使用的远程桌面软…

企业微信 API 接口调用教程:图文详解企业微信 API 的使用方法

本文通过 access_token 凭证的方式来讲解怎么调用 企业微信 API&#xff0c;并一步步介绍如何获取企业微信 API 的 corpsecret、corpid、access_token 凭证以及怎么向企业微信的应用发送消息。 企业微信 API 在线地址为&#xff1a;概述 - 企业微信 API &#xff0c;这个在线地…

大型架构设计的演进之路

Java全能学习面试指南&#xff1a;https://javaxiaobear.cn 今天我们一起看看大型互联网系统架构的演进之路&#xff0c;主要包含三部分内容。 第一部分是大型互联网系统的特点&#xff0c;分析大型互联网有哪些特点和挑战&#xff0c;它们是现在一些技术和架构方案产生的原因。…

性能测试 —— 性能测试常见的测试指标 !

一、什么是性能测试 先看下百度百科对它的定义&#xff0c;性能测试是通过自动化的测试工具模拟多种正常、峰值以及异常负载条件来对系统的各项性能指标进行测试。 我们可以认为性能测试是&#xff1a;通过在测试环境下对系统或构件的性能进行探测&#xff0c;用以验证在生产环…

网站有反爬机制就爬不了数据?那是你不会【反】反爬

目录 前言 一、什么是代理IP 二、使用代理IP反反爬 1.获取代理IP 2.设置代理IP 3.验证代理IP 4.设置代理池 5.定时更新代理IP 三、反反爬案例 1.分析目标网站 2.爬取目标网站 四、总结 前言 爬虫技术的不断发展&#xff0c;使得许多网站都采取了反爬机制&#xff…