【C++】内存对齐

本篇文章介绍C++中的内存对齐,后续介绍C的union和C++的variant的时候,需要用到这部分的知识。

占用内存

先回忆下C++各个数据类型占用的内存大小:

  1. int:所占内存大小:4byte = 32bit;
  2. char:所占内存大小:1byte = 8bit;

还有其他的数据类型,但是今天就只用这两个。
我们写个结构体:

struct s{int x;char y;
};

它占用多少byte的内存呢?并不是4+1=5,而是4+4=8.

int main()
{printf("%d\n",sizeof(s));  // 输出8return 0;
}

结果

分析内存

处理器并不是按字节块来存取内存的。它一般会以2字节,4字节,8字节,16字节甚至32字节为单位来存取内存.我们将上述这些存取单位称为内存存取粒度.写代码的人一般会觉得所有数据结构都会像数组一样有随机存取的特性,变量之间是紧挨着的,但是对于不同类型的变量来说,从内存向寄存器转移数据的过程并不总是顺利的。

以下图片来自https://blog.csdn.net/dxpqxb/article/details/90485917,我懒得画图了,就直接用现成的了。

现在有4byte的数据存放在内存中,他们的地址如下:

数据首地址末地址
A03
B14

假设内存存取粒度是1byte,取A和B都只需要取4次即可
1byte
当内存存取粒度是2byte时,A只需要取两次,分别为0和1、2和3;但是B从1开始,取2次取到了1、2和3,第4byte的数据还没取到,因此还需要取一次,总共取了3次。同时,还要把无用的第0byte和第5byte数据丢掉。
2byte
当内存存取粒度是4byte时,同样的道理,A只需要取1次4byte,B则需要取2次,并丢弃第0,第5-7byte的数据。
4byte
现在有了内存对齐的,int类型数据只能存放在按照对齐规则的内存中,比如说0地址开始的内存。那么现在该处理器在取数据时一次性就能将数据读出来了,而且不需要做额外的操作,提高了效率。
内存对齐

内存对齐

内存对齐的一个原则就是,不要让变量跨内存存取粒度存储。

每个特定平台上的编译器都有自己的默认“对齐系数”(也叫对齐模数)。gcc中默认#pragma pack(4),可以通过预编译命令#pragma pack(n),n = 1,2,4,8,16来改变这一系数。

有效对齐值:是给定值#pragma pack(n)和结构体中最长数据类型长度中较小的那个。有效对齐值也叫对齐单位。

了解了上面的概念后,我们现在可以来看看内存对齐需要遵循的规则:

  1. 结构体第一个成员的偏移量(offset)为0,以后每个成员相对于结构体首地址的 offset 都是该成员大小与有效对齐值中较小那个的整数倍,如有需要编译器会在成员之间加上填充字节。

  2. 结构体的总大小为 有效对齐值 的整数倍,如有需要编译器会在最末一个成员之后加上填充字节。

我们看下面三个结构体:

#include <stdio.h>
struct x1
{int i;char c1;char c2;
};struct x2
{char c1;int i;char c2;
};struct x3
{char c1;char c2;int i;
};int main()
{printf("%d\n", sizeof(x1)); printf("%d\n", sizeof(x2)); printf("%d\n", sizeof(x3)); return 0;
}

有效对齐值为4

不考虑结构体本身对外的偏移量,我们以x1为例,i的大小是4,有效对齐值也是4,只要保证偏移量为4的整数倍就行,因此i占用0,1,2,3;c1和c2的大小都是1,有效对齐值为4,只要保证偏移量为1的整数倍即可,因此占用4和5;结构体本身需要对外对齐,必须是4的整数倍,因此将6和7填充上。其他两个结构体也是一样的分析方式。

现在我们改变有效对齐值为2,输出结果如下:
有效对齐值为2
依然以x1为例,i的大小为4,有效对齐值是2,只要保证偏移量为2的整数倍就行,因此i占用0,1,2,3;c1和c2的大小都是1,有效对齐值为2,只要保证偏移量为1的整数倍即可,因此占用4和5;结构体本身需要对外对齐,必须是2的整数倍,无需填充。

其他

C++11

对齐的英文是alighment,C++11引入了一个函数alignof,可以直接获取类型T的内存对齐要求,也就是最大的成员大小与有效对齐值中较小那个。比如当有效对齐值为4时,上面3个结构体的alignof结果都是4.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/326484.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【C初阶——指针3】鹏哥C语言系列文章,基本语法知识全面讲解——指针(3)

本文由睡觉待开机原创&#xff0c;转载请注明出处。 本内容在csdn网站首发 欢迎各位点赞—评论—收藏 如果存在不足之处请评论留言&#xff0c;共同进步&#xff01; 这里写目录标题 前言&#xff1a;1.字符指针变量1.1一般用法1.2指向常量字符串 2.数组指针变量2.1数组指针变量…

分布式锁3: zk实现分布式锁4 使用临时顺序节点+watch监听+可重入(threadLocal)

一 zk实现分布式锁的可重入性 1.1 使用ThreadLocal属性 引入ThreadLocal线程局部变量保证zk分布式锁的可重入性。 1.2 关键代码说明 1.3 代码 1.3.1 初始化客户端 1.3.2 分布式锁代码 package com.atguigu.distributed.lock.config;import com.baomidou.mybatisplus.core…

《剑指 Offer》专项突破版 - 面试题 3 :前 n 个数字二进制形式中 1 的个数(C++ 实现)

目录 前言 方法一 方法二 方法三 前言 题目链接&#xff1a;338. 比特位计数 - 力扣&#xff08;LeetCode&#xff09; 题目&#xff1a; 输入一个非负数 n&#xff0c;请计算 0 到 n 之间每个数字的二进制形式中 1 的个数&#xff0c;并输出一个数组。例如&#xff0…

thingsboard规则节点功能记录(自用)

本文是对【ThingsBoard源码级分析规则节点使用第一季】 https://www.bilibili.com/video/BV1CT411e7vt/?p4&share_sourcecopy_web&vd_source9a5ca7ed3cff97385fdab4b6188e485c 学习的一些记录&#xff0c;加深自己的理解&#xff0c;在此声明。 asset profile switch…

跨国制造业组网方案解析,如何实现总部-分支稳定互联?

既要控制成本&#xff0c;又要稳定高效&#xff0c;可能吗&#xff1f; 在制造企业积极向“智造”发展、数字化转型的当下&#xff0c;物联网、人工智能、机器人等新型设备加入到生产、管理环节&#xff0c;为企业内部数据传输提出了更高的要求。而当企业规模扩大&#xff0c;数…

用ChatGPT方式编程!GitHub Copilot Chat全面开放使用

全球著名开源分享平台GitHub在官网宣布&#xff0c;经过几个月多轮测试的GitHub Copilot Chat&#xff0c;全面开放使用&#xff0c;一个用ChatGPT方式写代码的时代来啦&#xff01; 据悉&#xff0c;Copilot Chat是基于OpenAI的GPT-4模型&#xff0c;再结合其海量、优质的代码…

小红书 X WSDM 2024「对话式多文档问答挑战赛」火热开赛!

基于大语言模型&#xff08;LLM&#xff09;的对话问答机器人&#xff0c;已经成为当前人工智能领域学术界和工业界共同关注的的热门研究方向之一。在对话过程中&#xff0c;为大模型引入搜索结果&#xff0c;进行检索增强的生成&#xff08;Retrieval Augmented Generation&am…

NVIDIA Jetpack6.0DP使用过程中的问题

Jetpack6.0DP是2023年12月才发布&#xff0c; 操作系统使用了ubuntu 22.04&#xff0c; gcc是11.4&#xff0c;版本都很高&#xff0c; 用起来还存在一些问题 无法使用jtop https://forums.developer.nvidia.com/t/jtop-no-longer-works-on-jp-6-0-dp/275215 使用$ sudo -H p…

写给自己的CSDN博客之旅-如何从过程中获取价值-

勇于尝试 一个普通人如何在竞争越来越激烈的现代社会找到安身立业的方式&#xff1f; 作为一个注册CSDN已经有19年的老人&#xff0c;这些年失败的经历实在是太多太多了。 虽然注册CSDN很早&#xff0c;但是写博客确是在工作之后&#xff0c;也就是2015年。 在此之前有很多失…

什么?谁?w (who what)

文章目录 什么&#xff1f;谁&#xff1f;w (who & what)默认的显示不显示标题行简洁模式显示更多信息 什么&#xff1f;谁&#xff1f;w (who & what) w可以认为是加强版的who&#xff0c;果然越简洁越强大&#xff0c;就比如less比more是功能更多的。 w不仅可以显示…

Linux 上 Nginx 配置访问 web 服务器及配置 https 访问配置过程记录

目录 一、前言说明二、配置思路三、开始修改配置四、结尾 一、前言说明 最近自己搭建了个 Blog 网站&#xff0c;想把网站部署到服务器上面&#xff0c;本文记录一下搭建过程中 Nginx 配置请求转发的过程。 二、配置思路 web项目已经在服务器上面运行起来了&#xff0c;运行的端…

[概率论]重生至期末考前一个月看我如何力挽狂澜(下)

课本为《概率论与数理统计》ISBN 978-7-301-29547-2&#xff0c;此次整理4-8章的内容。 第四章 随机变量的数字特征 期望 频率具有波动性&#xff0c;概率具有稳定性。 离散型 设X是离散型随机变量&#xff0c;其分布律为&#xff1a;P{Xxk}pk ,k0,1,2,…… 两点分布 E(X)…