结构体的内存分配机制

2024-02-16 01:48
文章标签 内存 结构 分配机制

本文主要是介绍结构体的内存分配机制,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

首先,结构在C语言中也是一种数据类型,叫做聚组类型(还包括数组)。他和其他的数据类型是一样的,在定义一个结构体的时候,系统并不会为他真正的分配内存空间(定义的结构体变量要在编译的阶段才分配空间,而结构体指针要显示的使用malloca来分配空间),也就是说,在定义结构体这种数据类型的时候是不会分配内存空间的,只有在定义变量的时候,才会分配。

下面是摘自百度百科 对结构题存储的三点:

1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;  

2) 结构体每个成员相对于结构体首地址的偏移量都是成员大小的整数倍,如有需要编译器会  在成员之间加上填充字节;

3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节

 

下面是来自《c和指针》的介绍

struct s1{

  char a;

  int b;

  char c;

};

首先,结构体在存储的时候,结构体的首地址必须能够被其中最宽数据类型整除。(在s1中,最宽数据类型为int,在32位系统中为4Byte),

 

其次,参照第二条,第一个数据时char(已经保证了,结构的起始地址是4的整数倍),存储一个char,占一个Byte,要保证下一个int的存储起始地址是4的整数倍,所以要在char后面填充三个Byte,然后在存储第三个数据。

第三,最后一个也是char类型,他就占一个Byte,肯定是他存储位置的整数倍,最后参照第三条,结构体的总大小为最宽数据类型的整数倍,所以会在第二个char之后再填充三个Byte。

这样的话,总共占据的空间是1+3+4+1+3 = 12(红色为填充字符)

【但是】,调换一下结构中数据成员的顺序

 

struct s1{

  int b;

  char a;

  char c;

};

同样地分析4+1+1+2 = 8

相比之下,存储空间的效率提高33%。

 

以下是系统对结构体的内存分配的详细介绍:

1、结构体变量的首地址是结构体中最宽数据类型的整数倍。

  编译器在给结构体开辟空间时首先找到结构体中最宽的基本数据类型,然后寻找内存地址能是该基本数据类型的整倍的位置,作为结构体的首地址。

2结构体每个成员相对于结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节。

  为结构体的一个成员开辟空间之前,编译器首先检查预开辟空间的首地址相对于结构体首地址的偏移是否是本成员的整数倍,若是,则存放本成员,反之,则在本成员和上一个成员之间填充一定的字节,以达到整数倍的要求,也就是将预开辟空间的首地址后移几个字节

3、结构体的总大小为结构体中最宽基本数据成员的整数倍。如有需要,编译器将会在结构体的添加填充字符。

4、结构体中的数据成员按照所占空间从大到小的顺序来排列的话,这样存储空间就会得以提高。

4、现在对四条进行修正。在组织数据结构的数据成员的时候,可以将相同类型的成员放在一起,这样就减少了编译器为了对齐而添加的填充字符。


这篇关于结构体的内存分配机制的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/713156

相关文章

Vite 打包目录结构自定义配置小结

《Vite打包目录结构自定义配置小结》在Vite工程开发中,默认打包后的dist目录资源常集中在asset目录下,不利于资源管理,本文基于Rollup配置原理,本文就来介绍一下通过Vite配置自定义... 目录一、实现原理二、具体配置步骤1. 基础配置文件2. 配置说明(1)js 资源分离(2)非 JS 资

Redis实现高效内存管理的示例代码

《Redis实现高效内存管理的示例代码》Redis内存管理是其核心功能之一,为了高效地利用内存,Redis采用了多种技术和策略,如优化的数据结构、内存分配策略、内存回收、数据压缩等,下面就来详细的介绍... 目录1. 内存分配策略jemalloc 的使用2. 数据压缩和编码ziplist示例代码3. 优化的

深入解析C++ 中std::map内存管理

《深入解析C++中std::map内存管理》文章详解C++std::map内存管理,指出clear()仅删除元素可能不释放底层内存,建议用swap()与空map交换以彻底释放,针对指针类型需手动de... 目录1️、基本清空std::map2️、使用 swap 彻底释放内存3️、map 中存储指针类型的对象

Python内存优化的实战技巧分享

《Python内存优化的实战技巧分享》Python作为一门解释型语言,虽然在开发效率上有着显著优势,但在执行效率方面往往被诟病,然而,通过合理的内存优化策略,我们可以让Python程序的运行速度提升3... 目录前言python内存管理机制引用计数机制垃圾回收机制内存泄漏的常见原因1. 循环引用2. 全局变

Java集合中的链表与结构详解

《Java集合中的链表与结构详解》链表是一种物理存储结构上非连续的存储结构,数据元素的逻辑顺序的通过链表中的引用链接次序实现,文章对比ArrayList与LinkedList的结构差异,详细讲解了链表... 目录一、链表概念与结构二、当向单链表的实现2.1 准备工作2.2 初始化链表2.3 打印数据、链表长

创建springBoot模块没有目录结构的解决方案

《创建springBoot模块没有目录结构的解决方案》2023版IntelliJIDEA创建模块时可能出现目录结构识别错误,导致文件显示异常,解决方法为选择模块后点击确认,重新校准项目结构设置,确保源... 目录创建spChina编程ringBoot模块没有目录结构解决方案总结创建springBoot模块没有目录

SpringBoot利用树形结构优化查询速度

《SpringBoot利用树形结构优化查询速度》这篇文章主要为大家详细介绍了SpringBoot利用树形结构优化查询速度,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录一个真实的性能灾难传统方案为什么这么慢N+1查询灾难性能测试数据对比核心解决方案:一次查询 + O(n)算法解决

Oracle查询表结构建表语句索引等方式

《Oracle查询表结构建表语句索引等方式》使用USER_TAB_COLUMNS查询表结构可避免系统隐藏字段(如LISTUSER的CLOB与VARCHAR2同名字段),这些字段可能为dbms_lob.... 目录oracle查询表结构建表语句索引1.用“USER_TAB_COLUMNS”查询表结构2.用“a

MySQL 内存使用率常用分析语句

《MySQL内存使用率常用分析语句》用户整理了MySQL内存占用过高的分析方法,涵盖操作系统层确认及数据库层bufferpool、内存模块差值、线程状态、performance_schema性能数据... 目录一、 OS层二、 DB层1. 全局情况2. 内存占js用详情最近连续遇到mysql内存占用过高导致

最新Spring Security的基于内存用户认证方式

《最新SpringSecurity的基于内存用户认证方式》本文讲解SpringSecurity内存认证配置,适用于开发、测试等场景,通过代码创建用户及权限管理,支持密码加密,虽简单但不持久化,生产环... 目录1. 前言2. 因何选择内存认证?3. 基础配置实战❶ 创建Spring Security配置文件