【C语言】-结构体内存对齐。附详细图解

news/2024/7/7 17:50:00

文章目录

  • 前言
  • 1、结构体内存对齐的外在表现
  • 2、结构体对齐的基本规则
  • 3、为什么要结构体内存对齐?
  • 4、一些关于内存对齐的小细节


前言

这篇文章笔者总结了结构体内存对齐的内容,这部分内容非常重要,并且易错点。


1、结构体内存对齐的外在表现

先看代码:

struct S1
{
 	char c1;
	int i;
 	char c2;
};
printf("%d\n", sizeof(struct S1));
//练习2
struct S2
{
 	char c1;
 	char c2;
 	int i;
};
printf("%d\n", sizeof(struct S2));

这两段代码的运行结果是什么?都是6?
答案出乎意料:
在这里插入图片描述
分别是12、8
为什么会是这样的结果?
这就是笔者这篇博客要深入探讨的内容:结构体内存对齐

2、结构体对齐的基本规则

下面笔者给出原创超祥解图:
在这里插入图片描述
通过这张图,我们了解了结构体内存对齐的前三条规则,我们同理可以得到第二段代码的打印数为 8.与上述分析过程是一模一样的。
但是内存对齐不止三条规则。第四条规则为:

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

这里笔者就不给出第四条规则的详解了,相当于将嵌套的结构体当作一个变量,类似于上述变量开辟空间的过程。

3、为什么要结构体内存对齐?

这里笔者总结了两条原因:

  1. 平台原因(移植原因): 不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某些地址处取某些特 定类型的数据,否则抛出硬件异常。

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

第一条原因笔者不做过多赘述,具体意思如文字所描述。对于第二条原因,笔者再次通过画图加深你对第二条原因的理解。
在这里插入图片描述

所以总体来说,我们可以概括为:结构体内存对齐是为了用空间换取性能

4、一些关于内存对齐的小细节

1.当我们在设计结构体时,我们要让占用空间小的成员尽量集中在一起。

从而又能实现对齐又能不浪费空间。

2.我们可以通过#pragma pack来实现默认对齐数的修改

例如:

#include <stdio.h>
#pragma pack(8)//设置默认对齐数为8
struct S1
{
 char c1;
 int i;
 char c2;
};
#pragma pack()//取消设置的默认对齐数,还原为默认
#pragma pack(1)//设置默认对齐数为1
struct S2
{
 char c1;
 int i;
 char c2;
};
#pragma pack()//取消设置的默认对齐数,还原为默认
int main()
{
    //输出的结果是什么?
    printf("%d\n", sizeof(struct S1));
    printf("%d\n", sizeof(struct S2));
    return 0;
}

http://lihuaxi.xjx100.cn/news/94324.html

相关文章

Dart基础

Dart 强大的脚本语言&#xff0c;Dart是一门使用类和单继承的面向对象的语言&#xff0c;所有的对象都是类的实例&#xff0c;并且所有的类都是object的子类。Dart 中的抽象类主要用来定义标准&#xff0c;子类可以继承抽象类&#xff0c;也可以实现抽象类接口。把接口定义成抽…

JDK: JRE

序言 这个跟类加载有关. 其它的没啥好说的,直接说重点吧 重点 我们安装JDK后会有两个目录一个是JDK,一个是JRE.如下图所示: JDK: 这个是我们开发时需要往Eclipse或者Idear中引入的,里面主要包含了编译器,即把Java文件编译成Class文件的相关Jar.以及开发的过程所需要的一些工…

Neuron v2.2.2 发布:MQTT插件功能提升 、新增OPC DA驱动

近日&#xff0c;Neuron 2.2.2 正式发布。 这一最新版本对 MQTT 插件、SDK 开发包及其他商业驱动插件进行了优化和更新&#xff0c;为工业领域用户提供更加高效便捷的数据采集&#xff0c;欢迎下载试用。 MQTT 插件功能大幅提升 避免数据丢失 新增断线缓存数据功能。当 MQTT…

div嵌套居中的三种方法

html <div class"div1"><div class"div2">div2</div> </div>css .div1 {background-color: aqua;height: 100px;width: 100px;/* 方法一、三 *//* 子元素为绝对定位&#xff0c;父元素必须为相对定位 *//* position: relative; …

分布式版本控制系统Git的下载、安装与使用其复制GitHub项目代码的方法

本文介绍分布式开源版本控制系统Git的下载、安装&#xff0c;并基于Git实现克隆GitHub中项目代码的方法。 Git是一款开源软件&#xff0c;因此我们直接在Git的官方下载地址&#xff08;https://git-scm.com/downloads&#xff09;下载最新版本的Git即可。其中&#xff0c;在下图…

初始 JDBC

初始 JDBC 每博一文案 不要让你的焦虑&#xff0c;拖累你的人生&#xff0c;不知从何时起&#xff0c;焦虑挤进了你的人生&#xff0c;你被他困扰&#xff0c;每天莫名 悲伤&#xff0c;抑郁寡欢&#xff0c;你对生活一筹莫展&#xff0c;仿佛做什么都失去了兴趣。 因为孩子的…

基于 OpenMLDB 的联邦学习方案被国际数据挖掘学术会议 CIKM 录取

本周&#xff0c;数据挖掘领域的国际顶级学术会议 CIKM 2022 (https://www.cikm2022.org/) 正在美国亚特兰大举行。由第四范式和新加坡国立大学合作的论文 “A System for Time Series Feature Extraction in Federated Learning” 被 CIKM 录取。 该论文主要描述了基于 OpenM…

【附源码】计算机毕业设计SSM实验室安全准入考试系统

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…