结构体占用内存大小如何确定?-->结构体字节对齐 | C语言

这篇具有很好参考价值的文章主要介绍了结构体占用内存大小如何确定?-->结构体字节对齐 | C语言。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

一、什么是结构体

二、为什么需要结构体

三、结构体的字节对齐

3.1、示例1

3.2、示例2

3.3、示例3

 3.4、示例4

3.5、示例5

四、结构体字节对齐总结


一、什么是结构体

        结构体是将不同类型的数据按照一定的功能需 求进行整体封装,封装的数据类型与大小均可以由用户指定。

结构体定义,如下图1:

 

结构体内存,C语言,c语言,数据结构

图1

二、为什么需要结构体

        当需要存储大量重复的信息时,比如存储一个班级学生的信息,肯定包括姓名、学号、性别、年龄、成绩、家庭地址等项。这些项都是具有内在联系的,它们是一个整体,都表示同一个学生的信息。但如果将它们定义成相互独立的变量的话,就无法反映它们的内在联系,如下图2:

结构体内存,C语言,c语言,数据结构

 图2

        如果只是这样写的话,只是定义了一个学生,如果要定义第二个学生就要再写一遍。这样不仅麻烦,而且很容易混淆。要是能定义一个变量,而且这个变量正好包含这六个项,即将它们合并成一个整体的话就好了。结构体就是为了解决这个问题而产生的。

三、结构体的字节对齐

现在来探讨一个问题,结构体的大小是如何划分的呢?

3.1、示例1

        有这样一个程序,结构占用内存大小按理来说应该是,char占1个字节,int占4个字节,1+4=5,结构体占用内存大小应该是5个字节才对。

#include <stdio.h>

struct STUDENT
	{
		char a;
		int b;
	}data;

int main()
{
	printf("a的地址为:%p,b的地址为:%p\n", &data.a, &data.b);  //%p是取地址符
	printf("结构体总大小为:%d\n", sizeof(data));
   
   return 0;
}

以上程序输出结果如下图3所示:

结构体内存,C语言,c语言,数据结构图3

内存分配图下图4:

结构体内存,C语言,c语言,数据结构

        图4

分析:

        事实上结构体大小是8个字节,b占4字节我们能理解,但a是char型,char型不是占1字节吗,这里为什么占4字节?其实不是它占了4字节,它占的还是1字节,只不过结构体中有一个字节对齐的概念。


那么到底是怎么存储的呢?


        就是按字节对齐的方式存储的!即以结构体成员中占内存最多的数据类型所占的字节数为标准,所有的成员在分配内存时都要与这个长度对齐。


        以上面这个程序为例,结构体变量data的成员中占内存最多的数据类型是int型,其占4字节的内存空间,那么所有成员在分配内存时都要与4字节的长度对齐。也就是说,虽然char只占1字节,但是为了与4字节的长度对齐,它后面的3字节都会空着。


3.2、示例2

         按上面的结论,最大的是int占4个字节,那么按4字节对齐,大小应该是4+4+4=12;

#include <stdio.h>

struct STUDENT
	{
		char a;
		cahr c;
		int b;
	}data;

int main()
{
	printf("a的地址为:%p,b的地址为:%p,c的地址为:%p\n", &data.a, &data.b, &data.c);
	printf("结构体总大小为:%d\n", sizeof(data));
   
   return 0;
}

结果如下图5:

结构体内存,C语言,c语言,数据结构

图5


 但大小实际上并没有变化,内存分配为下图6所示:

结构体内存,C语言,c语言,数据结构

图6


分析:

        在分配了a的内存后,c希望和a近邻,并且因为内存对齐a申请了4个字节,在a相邻的位置可以存放,所以c与a共同占用一个4字节内存。

3.3、示例3

        首先最长的数据类型占4字节,所以是以4字节对齐。1+1+1+1+4+4=12

#include <stdio.h>

struct STUDENT
	{
		char a;
		char c;
		char d;
		char f;
		char e;
		int b;
	}data;

int main()
{
	printf("a的地址为:%p,b的地址为:%p,c的地址为:%p,d的地址为:%p,f的地址为:%p,e的地址为:%p\n", &data.a, &data.b, &data.c, &data.d, &data.f, &data.e);
	printf("结构体总大小为:%d\n", sizeof(data));
   
   return 0;
}

输出结果如下图7:

结构体内存,C语言,c语言,数据结构

图7


即该结构体变量分配内存时如下图8:

结构体内存,C语言,c语言,数据结构

图8

分析:

        首先最长的数据类型占4字节,所以是以4对齐。a占1字节,b接在a后面占1字节,c接在b后面占1字节,d接在c后面占1字节,此时满4字节了,e再来就要另起一行。f想紧接着e后面分配,但e后面还剩3字节,小于int类型的4字节,所以f另起一行。

 3.4、示例4

        首先最长的数据类型占4字节,所以是以4字节对齐。4+4+4=12。

#include <stdio.h>

struct STUDENT
	{
		char a;
		int c;
		char b;
	}data;

int main()
{
	printf("a的地址为:%p,b的地址为:%p,c的地址为:%p\n", &data.a, &data.b, &data.c);
	printf("结构体总大小为:%d\n", sizeof(data));
   
   return 0;
}

输出结果如下图9:

结构体内存,C语言,c语言,数据结构

图9


内存分配如下图10:

结构体内存,C语言,c语言,数据结构

图10

分析:

        首先最长的数据类型占4字节,所以是以4对齐。a占1字节,c希望与a近邻,但3字节不足以存放int,故重新再起一行,所以a占4字节。b也希望与a近邻,但a空间不足以存放b,故b也重新起一行占4个字节。

 

3.5、示例5

        首先最长的数据类型占4字节,所以是以4字节对齐。但出现了数组,大小应该怎样计算呢?

#include <stdio.h>

struct STUDENT
{
	char name[3];
	int age;
	char sex;
	char score;
}data;


int main()
{
	printf("%p,%p,%p,%p,%p,%p\n", &data.name[0], &data.name[1], &data.name[2], &data.age, &data.sex, &data.score);
	printf("结构体总大小为:%d\n", sizeof(data));
   
   return 0;
}

输出结果如下图11:

结构体内存,C语言,c语言,数据结构

 图11

分析:

        出现了数组,数组可以看做多个char类型,依然是占1字节,所以内存大小为:4+4+4=12。

四、结构体字节对齐总结

概念总结:

        1)可以知道,同样的数据类型,只不过交换了一下位置,结构体变量data所占的内存空间就由8字节变成12字节,多了4字节。这就告诉我们,在声明结构体类型时,各类型成员的前后位置会对该结构体类型定义的结构体变量所占的字节数产生影响;

        2)没有规律的定义会增加系统给结构体变量分配的字节数,降低内存分配的效率。但这种影响对操作系统来说几乎是可以忽略不计的!所以我们在写程序的时候,如果有心的话,声明结构体类型时就按成员类型所占字节数从小到大写,或从大到小写;

        3)但是如果没有按规律书写的话也不要紧,声明结构体类型时并非一定要从小到大声明,只是为了说明结构体字节对齐这个概念。

使用总结:

        1)按占用最大的字节对齐;

        2)占用内存可以共用(前提是足以同时保存);

        3)不足以存放时,会出现申请一个内存空间;

        4)合理书写顺序可以节省CPU资源,当量足够大时,有可能会影响系统运行效率。

        如果在单片机使用RTOS,RTOS管理的内存空间固定,但因为结构体申请了很多内存,在使用时,有可能因为内存不足而产生不必要的错误。文章来源地址https://www.toymoban.com/news/detail-796985.html

到了这里,关于结构体占用内存大小如何确定?-->结构体字节对齐 | C语言的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C语言——结构体类型(二)【结构体内存对齐,结构体数组】

    📝前言: 上一讲结构体类型(一)中,我们讲述了有关 结构体定义,创建,初始化和引用 的内容,这一讲,我们进一步学习结构体的相关知识: 1,结构体内存对齐 2,结构体数组 🎬个人简介:努力学习ing 📋个人专栏:C语言入门基础 🎀CSDN主页 愚润求学 🌄每日鸡汤:

    2024年01月24日
    浏览(54)
  • 【C语言高阶篇】结构体 —— 什么是内存对齐?

    🎬 鸽芷咕 :个人主页  🔥 个人专栏 :《C语言初阶篇》 《C语言进阶篇》 ⛺️生活的理想,就是为了理想的生活!    🌈 hello! 各位宝子们大家好啊,今天给大家带来的是结构体的内存对齐这部分知识,可以说是干货满满啦!    ⛳️ 在我们C语言的面试题中,结构体最

    2024年02月14日
    浏览(42)
  • STM32 大小端与字节对齐使用记录

    串口数据包解析 接收到的数据包: 其中数据内容为: 我们设计的结构体 使用内容复制函数 想要的数据: 实际的数据: 解决方法: CMSIS都已经给你写好的,请看core_cm3.h 执行完这个代码后 我们希望 实际上 解决方法:

    2024年02月07日
    浏览(26)
  • 【C语言13】结构体的声明,定义与结构体的内存对齐

    通俗的说,结构体就是一个类的集合,如同整形数组是整形数字的集合体,结构体也是一些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。 如果我们要表达一本书,那么这本书的元素有什么呢,书的名字,书的作者,书的创作日期~,而c语言中内置

    2024年02月13日
    浏览(57)
  • 深入了解C语言中的结构体类型与内存对齐

    在C语言中,结构体是一种 自定义的数据类型 , 它允许我们将不同类型的数据组合在一起,形成一个新的数据类型 。结构体的使用为我们解决了一些复杂数据的表示和处理问题,不仅限于单单的整型或者字符。本文将深入探讨结构体类型、结构体变量的创建和初始化,并详

    2024年04月11日
    浏览(30)
  • C语言——数据在内存中的存储【整型数据在内存中的储存,大小端字节序储存,浮点型数据在内存中的储存】

    📝前言: 在前面的三篇文章中我们已经完成了对字符函数和字符串函数的学习,现在就让我们探索新领域,更加深入的理解** 数据在内存中的存储方式 **: 1,整数在内存中的存储 2,⼤⼩端字节序存储 3,浮点数在内存中的存储 🎬个人简介:努力学习ing 📋个人专栏:C语言

    2024年02月04日
    浏览(36)
  • 【C语言】自定义类型:结构体深入解析(二)结构体内存对齐&&宏offsetof计算偏移量&&结构体传参

    本小节,我们学习结构的内存对齐,理解其对齐规则,内存对齐包含结构体的计算,使用宏 offsetof 计算偏移量,为什么要存在内存对齐?最后了解结构体的传参文章干货满满!学习起来吧😃! 结构体内存对齐指的是 结构体中各成员变量在内存中的存储位置按照一定规则对齐

    2024年02月04日
    浏览(35)
  • C语言自定义类型:结构体的使用及其内存对齐【超详细建议点赞收藏】

    结构是一些值的集合,这些值称为 成员变量 。 结构的每个成员可以是不同类型的变量 。 注意 : 成员列表可以是不同类型的变量; 成员后一定要有分号; 花括号后也有一个分号。 例如描述一个学生: 注意:上述代码没有创建变量,也没有初始化, 只是声明了一个结构体类

    2024年03月13日
    浏览(38)
  • 【C语言高阶篇】C语言面试必考知识点,结构体的内存对齐我看还有谁不会!

    🎬 鸽芷咕 :个人主页  🔥 个人专栏 :《C语言初阶篇》 《C语言进阶篇》 ⛺️生活的理想,就是为了理想的生活!    🌈 hello! 各位宝子们大家好啊,今天给大家带来的是结构体的内存对齐这部分知识,可以说是干货满满啦!    ⛳️ 在我们C语言的面试题中,结构体最

    2024年02月16日
    浏览(33)
  • CAP结构体之字节对齐

    🍅 我是 蚂蚁小兵 ,专注于车载诊断领域,尤其擅长于对CANoe工具的使用 🍅 寻找组织 ,答疑解惑,摸鱼聊天,博客源码,点击加入👉【相亲相爱一家人】 🍅 玩转CANoe,博客目录大全,点击跳转👉 CAPL为什么也要理解字节对齐呢? 一般情况下,我们在定义/使用结构体的情

    2024年02月12日
    浏览(30)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包