返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C语言热门考点结构体与内存对齐详解
  • 188
分享到

C语言热门考点结构体与内存对齐详解

2024-04-02 19:04:59 188人浏览 安东尼
摘要

目录一、引例二、小试牛刀三、嵌套结构体的特殊情况四、关于为什么存在内存对齐1.平台原因(移植原因): 2.性能原因: 总结一、引例 到底什么是结构体内存对齐,我们用一段代码来介绍一下

一、引例

到底什么是结构体内存对齐,我们用一段代码来介绍一下


struct S1
{
	char c1;//1字节
	int a;//4字节
	char c2;//1字节
};
int main()
{
	printf("%d\n", sizeof(struct S1));
	//这里打印12
}

先来解释S1,结构体S1中有2个char类型,1个int类型。那按道理应该是占2*1+4=6个字节啊,为什么打印的是12呢?到这里,我们必须要来了解一下结构体内存对齐的规则:

1.结构体的第一个成员永远放在结构体起始位置偏移量为0的位置

对于偏移量你可以这样理解:数组下标为0的相对它自己偏移量为0,下标为1的相对下标为0的偏移量为1…
举例说明:

在这里插入图片描述

S1第一个成员是c1,它会被放在结构体起始位置偏移量为0的位置,如下图红色部分

在这里插入图片描述

2.从第二个成员开始,总是放在偏移量为一个对齐数的整数处,对齐数=编译器默认的对齐数和变量自身大小的较小值

对齐数=min(编译器默认的对齐数,变量自身大小)
linux-没有对齐数,VS下对齐数默认为8

我们仍以S1这个结构体进行举例,结构体第二个成员是int类型的a,占4个字节,笔者VS环境下默认对齐数是8,取两者较小值是4,那a应该放到偏移量为4的倍数上

在这里插入图片描述

放到4的倍数上也就说可以放在偏移量为4这里,偏移量为1,2,3的这3个空间就白白被浪费了。而a是int型占4个字节,所以会一直占用到偏移量为7的位置。

接下来是结构体的第三个成员,char类型的c2,c2占1个字节,VS环境下默认对齐数是8,取较小值为1,也就是说只要是1的倍数的偏移量都可以放,我们紧接着放在a后面,也就是偏移量8的位置

在这里插入图片描述

那到这里结构体3个成员都用完了啊,只有8个啊,为什么打印是12呢?这里就要涉及结构体内存对齐的第3个规则

3.结构体的总大小必须是各个成员的对齐数中最大的那个对齐数的整数倍

我们由前面讲解知道结构体三个成员c1,a,c2对齐数分别为1,4,1这三个中最大对齐数是4,总大小要为4的整数倍,那这时候肯定有小伙伴会问:我们现在不是对齐到8了嘛,8不是4的倍数吗?注意!这里说的是空间总大小,而8是所谓的偏移量,偏移量是从0开始算的,到8已经有9个空间了,所以我们这里空间要到12,也就是偏移量到11

在这里插入图片描述

(后面加上的三个空间用不到,但是由于规定还是算在结构体总空间内)

二、小试牛刀

我们再来看一道类似的题目

代码如下(示例):


struct S2
{
	char c1;//1字节
	char c2;//1字节
	int a;//4字节
};
int main()
{
	printf("%d\n", sizeof(struct S2));
	//这里打印8
}

首先第一个结构体成员是char类型的c1,由规则1,它会直接被放在偏移量为0的位置
(图示灰色部分)

在这里插入图片描述

第二个成员是char类型的c2,占1字节,VS下默认对齐数是8,取较小值是1,只要放在偏移量为1的倍数上即可(任意位置),紧跟着0,放在偏移量为1处(图示红色部分)

在这里插入图片描述

最后一个成员int类型的a,占4个字节,VS环境下默认对齐数是8,取较小者4,放在偏移量为4的整数倍处,也就是4这里,然后由于int占4个字节所以一直占用到偏移量7处

在这里插入图片描述

再来看看规则3,结构体的总大小必须是各个成员的对齐数中最大的那个对齐数的整数倍,也就是4的倍数,我们现在正好是占8个空间,8正好是4的倍数,所以就不用再往下浪费空间了,打印出8

三、嵌套结构体的特殊情况

代码如下(示例):


struct S3
{
	double d;//double占8字节,默认对齐数8,取较小值,对齐数8
	char c;//对齐数1
	int i;//对齐数4
};
struct S4
{
	char c1;
	struct S3 s3;
	double d;
};
int main()
{
	printf("%d\n", sizeof(struct S4));
}

关于结构体S3我们可以采用和前面S1、S2一样的方法计算出来是占16个字节空间,我们这里重点讨论S4,对S3有兴趣的小伙伴可自行求解。

S4中的第一个成员c1,按规则1直接放在偏移量为0处,第二个成员s3怎么办呢?这里涉及结构体内存对齐的第四个规则:

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

s3这个结构体三个成员最大对齐数是8,也就是要对齐到偏移量为8的倍数处,然后s3是占16个字节,所以一直占到偏移量23处(s3结构体对齐数是本身s3结构体三个成员中最大对齐数)

ps:在VS环境中,嵌套结构体的最大对齐数超过8,仍然用8做最大对齐数(比默认对齐数大了,取较小值就取默认对齐数了)

在这里插入图片描述

S4最后一个成员double类型的d占8字节,默认对齐数8,对齐数取8,然后放在偏移量为对齐数的整数倍处,正好往下放在24处,本身占8字节所以占到31

在这里插入图片描述

偏移量0-31共占32字节,S4中的成员c1,s3,d对齐数分别为1,8,8所以最大对齐数是8,32恰是8的倍数,所以这里不用再浪费空间来满足 “结构体的总大小必须是各个成员的对齐数中最大的那个对齐数的整数倍”这个规则,结构体总大小就是32

四、关于为什么存在内存对齐

1.平台原因(移植原因):

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

2.性能原因:

数据结构(尤其是栈),应尽可能地在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅仅需要1次
总体来说:结构体的内存对齐是用空间换时间

总结

本文介绍了结构体内存对齐的四大规则,并举例说明了如何进行方法的操作,对于其中特殊的嵌套结构体内存对齐也进行了相应讲解,希望读者在学习完本文后能对结构体内存对齐有一个系统的认识。祝读者学业有成!

更多关于C语言结构体与内存对齐的资料请关注编程网其它相关文章!

--结束END--

本文标题: C语言热门考点结构体与内存对齐详解

本文链接: https://lsjlt.com/news/155209.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • C语言热门考点结构体与内存对齐详解
    目录一、引例二、小试牛刀三、嵌套结构体的特殊情况四、关于为什么存在内存对齐1.平台原因(移植原因): 2.性能原因: 总结一、引例 到底什么是结构体内存对齐,我们用一段代码来介绍一下...
    99+
    2024-04-02
  • C语言详解热门考点结构体内存对齐
    目录一、为什么存在内存对齐二、如何计算?(考点)三、手撕代码一、为什么存在内存对齐         大...
    99+
    2024-04-02
  • C语言结构体内存对齐详解
    目录实例一:分析:存储结构图如下实例二: 分析:存储结构如下实例三:  分析:存储结构如下 实例四:分析:存储结构图如下总结1、结构体内存对齐...
    99+
    2024-04-02
  • C语言中结构体怎么与内存对齐
    本篇内容介绍了“C语言中结构体怎么与内存对齐”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!1.结构体类型C语言中的2种类型:原生类型和自定义...
    99+
    2023-06-20
  • C语言详解结构体的内存对齐与大小计算
    目录结构体的内存对齐1、计算结构体的大小2、结构体的对齐规则3、为什么存在内存对齐?4、总结结构体的内存对齐 1、计算结构体的大小 struct S1 { char c1; // ...
    99+
    2024-04-02
  • C语言中结构体与内存对齐实例解析
    1.结构体类型 C语言中的2种类型:原生类型和自定义类型,结构体类型是一种自定义类型。 2.结构体使用时先定义结构体类型再用类型定义变量 -> 结构体定义时需要先定义结构体类型...
    99+
    2024-04-02
  • C语言程序中结构体的内存对齐详解
    目录一、为什么存在内存对齐二、结构体的内存对齐四规则三、举例一、为什么存在内存对齐 1.平台原因(移植原因): 不是所有的硬件平台都能访问任意地址上的任意数据的;某些硬件平台只能在某...
    99+
    2022-11-13
    C语言结构体内存对齐 C语言 内存对齐 C语言 结构体
  • C语言中结构体与内存对齐的方法
    这篇文章主要介绍了C语言中结构体与内存对齐的方法的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇C语言中结构体与内存对齐的方法文章都会有所收获,下面我们一起来看看吧。1.结构体类...
    99+
    2024-04-02
  • C语言详细分析结构体的内存对齐
    目录一.结构体二.结构体内存对齐1.非嵌套结构体的大小2.含嵌套结构体的大小三.为什么要内存对齐1.平台原因(移植原因)2.性能原因一.结构体 结构体 (struct)是一种数据结构...
    99+
    2024-04-02
  • C语言结构体中内存对齐的问题理解
    目录前言思考结构体在内存中开辟空间时内存对齐的规则为什么存在内存对齐1.平台的原因2.性能的原因前言 学C的同学应该知道~ 想精通C语言就不得不面对—指针与内存 续上次指...
    99+
    2024-04-02
  • C语言中结构体的内存对齐规则讲解
    目录1.结构体的内存对齐规则2.例子3.为什么存在内存对齐4.如何修改默认对齐数1.结构体的内存对齐规则 1.第一个成员在与结构体变量偏移量为0的地址处。 2.其他成员变量都放在对齐...
    99+
    2024-04-02
  • C语言详细分析结构体的内存对齐规则
    目录引例结构体内存对齐规则那么为什么要有内存对齐呢如何优化修改默认对齐数结构体的内存对齐是一个特别热门的知识点! 引例 #include<iostream> using ...
    99+
    2024-04-02
  • C语言结构体嵌套与对齐超详细讲解
    目录嵌套结构体结构体内存对齐32位的操作系统64位的操作系统嵌套结构体 格式:typedef struct 结构体名 {struct 结构体名1 结构体变量名1;struct 结构体...
    99+
    2022-12-26
    C语言结构体嵌套 C语言结构体对齐 C语言结构体嵌套与对齐
  • C语言结构体的内存对齐与大小怎么计算
    这篇文章主要讲解了“C语言结构体的内存对齐与大小怎么计算”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“C语言结构体的内存对齐与大小怎么计算”吧!结构体的内存对齐1、计算结构体的大小struc...
    99+
    2023-06-30
  • C语言中结构体、联合体的成员内存对齐情况
    前言 最近项目进行中,遇到一个小问题,在数据协议传输过程中,我为了方便解析,就定义了一个结构体,在数据的指针传入函数的时候,我用定义好的结构体进行强制转化,没想到一直解析失败,调试很...
    99+
    2024-04-02
  • C语言中结构体struct怎么对齐
    这篇文章主要介绍“C语言中结构体struct怎么对齐”,在日常操作中,相信很多人在C语言中结构体struct怎么对齐问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”C语言中结构...
    99+
    2024-04-02
  • C语言深入回顾讲解结构体对齐
    目录结构体对齐问题结构体嵌套结构体强制内存对齐拓展求结构体成员的偏移量结构体对齐问题 1、知识点的引入: struct data1 { char a;//1B int...
    99+
    2024-04-02
  • 详解C语言内核中的链表与结构体
    Windows内核中是无法使用vector容器等数据结构的,当我们需要保存一个结构体数组时,就需要使用内核中提供的专用链表结构LIST_ENTRY通过一些列链表操作函数对结构体进行装...
    99+
    2024-04-02
  • 详解Go语言中的内存对齐
    目录前言基础知识看个问题什么是内存对齐为什么需要内存对齐unsafe.AlignOf()内存对齐规则举个例子空结构体的对齐规则总结前言 前面有篇文章我们学习了 Go 语言空...
    99+
    2024-04-02
  • C语言结构体struct详解
    目录结构体的概念结构体类型的声明结构体变量的创建typedef关键字结构体的嵌套结构体变量的初始化结构体成员的访问结构体的传参总结结构体的概念 结构体是由一系列具有相同类型或不同类型...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作