C++ 结构体内存方式

2024-06-17 01:08
文章标签 c++ 方式 结构 体内

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

对于这个问题,主要有两方面的内容。其一,内存优化,其二,存储顺序

一、内存优化

所谓的内存优化是结构体成员的存储按成员中数据宽度最宽的成员对齐的一种内存对齐方式。这样做的最大好处就是可以提高处理速度(感兴趣的可以查一下资料),但会增大存储空间,这种优化是对时间和空间的一种权衡。

  • 如果结构体中数据成员的最大宽度为32位的,即4字节,那么该结构体的大小将是4字节的倍数,而不是将所有成员宽度加起来的大小。同样,如果数据成员中最大宽度为64位的,那么改及饿哦固体大小将是8字节的倍数。

    • 猜想一下,下里两个结构的大小是多少?可以输出一下sizeof的结果

      //例 1
      struct str1
      {
      int  a;     //占用4字节,有效内容4字节
      char b;     //占用4字节,有效内容1字节
      };
      struct str2
      {
      double a;
      char  b;        //占用8字节,有效内容1字节
      };
      //初始化代码
      str1 str_1 = { 1024,'A' };
      str2 str_2 = { 10.5,'A' };
    • 答案是:str1的大小为8,str2的大小为16。下图是我截取的内存图:


    这里写图片描述

    第一行为str_2.a的内存
    第二行为str_2.b的内存,cc均为栈区的填充内容
    第四行前4字节为str_1.a的内存
    第四行后4字节为str_1.b的内存

  • 那这样的话岂不是结构体大小为数据成员中最大数据宽度*数据成员个数了?也不是

    • 这个结构体是多大?是24字节吗?

      //例 2
      struct str3
      {
      double a;
      int b;
      char c;
      };
      //初始化代码
      str3 str_3 = { 10.5,1024,'A' };
    • 答案是16字节,可以和上面的例子对比一下。

      这里写图片描述

    第一行8字节为str_3.a的内存
    第二行前4字节为str_3.b的内存
    第二行后4字节为str_3.c的内存

  • 总结一下
    可以把这种对齐方式比作使用特定大小的瓶子(箱子)装东西。如果将64位数据作为最大瓶子,那么装东西时所占的空间是以瓶子为单位的,你在大瓶子中装了一个小东西,那么它所占的空间还是大瓶子的空间(第一个例子的解释)。同时,大瓶子中还可以装小瓶子,小瓶子中还可以装更小的瓶子(第二个里的解释)

    编译器默认有内存优化,在编程是也可以手动修改对齐粒度
    #pragma pack(1) // 按照1字节方式进行对齐,括号中可以指定任意数
    #pragma pack() // 取消指定的对齐方式

二、存储顺序
  • 跟数组存储顺序一样,越往前的数据越在低地址处。

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



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

相关文章

Android实现定时任务的几种方式汇总(附源码)

《Android实现定时任务的几种方式汇总(附源码)》在Android应用中,定时任务(ScheduledTask)的需求几乎无处不在:从定时刷新数据、定时备份、定时推送通知,到夜间静默下载、循环执行... 目录一、项目介绍1. 背景与意义二、相关基础知识与系统约束三、方案一:Handler.postDel

gradle第三方Jar包依赖统一管理方式

《gradle第三方Jar包依赖统一管理方式》:本文主要介绍gradle第三方Jar包依赖统一管理方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录背景实现1.顶层模块build.gradle添加依赖管理插件2.顶层模块build.gradle添加所有管理依赖包

C#如何调用C++库

《C#如何调用C++库》:本文主要介绍C#如何调用C++库方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录方法一:使用P/Invoke1. 导出C++函数2. 定义P/Invoke签名3. 调用C++函数方法二:使用C++/CLI作为桥接1. 创建C++/CL

Linux之systemV共享内存方式

《Linux之systemV共享内存方式》:本文主要介绍Linux之systemV共享内存方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、工作原理二、系统调用接口1、申请共享内存(一)key的获取(二)共享内存的申请2、将共享内存段连接到进程地址空间3、将

Maven中引入 springboot 相关依赖的方式(最新推荐)

《Maven中引入springboot相关依赖的方式(最新推荐)》:本文主要介绍Maven中引入springboot相关依赖的方式(最新推荐),本文给大家介绍的非常详细,对大家的学习或工作具有... 目录Maven中引入 springboot 相关依赖的方式1. 不使用版本管理(不推荐)2、使用版本管理(推

C#使用StackExchange.Redis实现分布式锁的两种方式介绍

《C#使用StackExchange.Redis实现分布式锁的两种方式介绍》分布式锁在集群的架构中发挥着重要的作用,:本文主要介绍C#使用StackExchange.Redis实现分布式锁的... 目录自定义分布式锁获取锁释放锁自动续期StackExchange.Redis分布式锁获取锁释放锁自动续期分布式

Java对象转换的实现方式汇总

《Java对象转换的实现方式汇总》:本文主要介绍Java对象转换的多种实现方式,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录Java对象转换的多种实现方式1. 手动映射(Manual Mapping)2. Builder模式3. 工具类辅助映

Spring Boot读取配置文件的五种方式小结

《SpringBoot读取配置文件的五种方式小结》SpringBoot提供了灵活多样的方式来读取配置文件,这篇文章为大家介绍了5种常见的读取方式,文中的示例代码简洁易懂,大家可以根据自己的需要进... 目录1. 配置文件位置与加载顺序2. 读取配置文件的方式汇总方式一:使用 @Value 注解读取配置方式二

JAVA保证HashMap线程安全的几种方式

《JAVA保证HashMap线程安全的几种方式》HashMap是线程不安全的,这意味着如果多个线程并发地访问和修改同一个HashMap实例,可能会导致数据不一致和其他线程安全问题,本文主要介绍了JAV... 目录1. 使用 Collections.synchronizedMap2. 使用 Concurren

C++如何通过Qt反射机制实现数据类序列化

《C++如何通过Qt反射机制实现数据类序列化》在C++工程中经常需要使用数据类,并对数据类进行存储、打印、调试等操作,所以本文就来聊聊C++如何通过Qt反射机制实现数据类序列化吧... 目录设计预期设计思路代码实现使用方法在 C++ 工程中经常需要使用数据类,并对数据类进行存储、打印、调试等操作。由于数据类