当前位置: 首页 > news >正文

c++中的对齐问题

c++中的对齐问题

需要对齐的原因

尽管内存是以字节为单位,但是大部分处理器并不是按字节块来存取内存的.它一般会以双字节,四字节,8字节,16字节甚至32字节为单位来存取内存,我们将上述这些存取单位称为内存存取粒度.

现在考虑4字节存取粒度的处理器取int类型变量(32位系统),该处理器只能从地址为4的倍数的内存开始读取数据。

假如没有内存对齐机制,数据可以任意存放,现在一个int变量存放在从地址1开始的联系四个字节地址中,该处理器去取数据时,要先从0地址开始读取第一个4字节块,剔除不想要的字节(0地址),然后从地址4开始读取下一个4字节块,同样剔除不要的数据(5,6,7地址),最后留下的两块数据合并放入寄存器.这需要做很多工作.

bg1

对齐的规则

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

注意:
#pragma pack(n)中的n可以取(1 , 2 , 4 , 8 , 16)中的任意一值。

2)规则:

  • 结构体变量的首地址是有效对齐值(对齐单位)的整数倍。

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

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

  • 结构体内类型相同的连续元素将在连续的空间内,和数组一样。

运用上面的规则,下面通过实际的例子进行计算。

例1:

#include <iostream>struct MyStruct {char c;int i;short s;
};int main()
{MyStruct obj;std::cout << "start addr of obj = " << (void*)&obj << std::endl;std::cout << "offset of c = "  << offsetof(MyStruct,c) << std::endl;std::cout << "offset of i = " << offsetof(MyStruct,i) << std::endl;std::cout << "offset of s = " << offsetof(MyStruct,s) << std::endl;std::cout << "sizeof MyStruct = " << sizeof(MyStruct);
}

执行结果如下:

start of obj = 0x7fff2e8d1e94
offset of c = 0
offset of i = 4
offset of s = 8
sizeof MyStruct = 12

结构中最长的数据类型是int,长度也为4。因此结构体的有效对齐值是4。

对于c变量而言,没有悬念,将排在0偏移地址处。

对于变量i,类型为int,长度为4,int和有效对齐值的最小值为4,因此i需要排布在4的整数倍上,因此第一个符合要求的偏移量就是4。

对于变量s,类型为short,长度为2,short和有效对齐值二者中的最小值为2,第一个符合要求的地址为8。

到目前为止,使用的空间大小是10,而结构体大小需要满足有效对齐值的整数倍,因此需要2个填充,因此结构体最终大小是12。

MyStruct分布

例2:

#include <iostream>
#pragma pack(2)
struct MyStruct {char c;int i;short s;
};int main()
{MyStruct obj;std::cout << "start addr of obj = " << (void*)&obj << std::endl;std::cout << "offset of c = "  << offsetof(MyStruct,c) << std::endl;std::cout << "offset of i = " << offsetof(MyStruct,i) << std::endl;std::cout << "offset of s = " << offsetof(MyStruct,s) << std::endl;std::cout << "sizeof MyStruct = " << sizeof(MyStruct);
}

执行结果如下:

start addr of obj = 0x7fff488e3418
offset of c = 0
offset of i = 2
offset of s = 6
sizeof MyStruct = 8

首先#pragma pack设置的对齐值是2,结构中最长的数据类型是int,长度也为4。因此结构体的有效对齐值是2。

对于c变量而言,没有悬念,将排在0偏移地址处。

对于变量i,类型为int,长度为4,int和有效对齐值的最小值为2,因此i需要排布在2的整数倍上,因此第一个符合要求的偏移量就是2。

对于变量s,类型为short,长度为2,short和有效对齐值二者中的最小值为2,第一个符合要求的地址为6。

到目前为止,使用的空间大小是8,已经满足结构体大小是有效对齐值的整数倍的要求。

MyStruct分布2

#include <iostream>
#pragma pack(1)
struct MyStruct {char c;int i;short s;
};int main()
{MyStruct obj;std::cout << "start addr of obj = " << (void*)&obj << std::endl;std::cout << "offset of c = "  << offsetof(MyStruct,c) << std::endl;std::cout << "offset of i = " << offsetof(MyStruct,i) << std::endl;std::cout << "offset of s = " << offsetof(MyStruct,s) << std::endl;std::cout << "sizeof MyStruct = " << sizeof(MyStruct);
}

执行结果如下:

start addr of obj = 0x7ffe96c067a9
offset of c = 0
offset of i = 1
offset of s = 5
sizeof MyStruct = 7

首先#pragma pack设置的对齐值是1,结构中最长的数据类型是int,长度也为4。因此结构体的有效对齐值是1。

对于c变量而言,没有悬念,将排在0偏移地址处。

对于变量i,类型为int,长度为4,int和有效对齐值的最小值为,因此i需要排布在2的整数倍上,因此第一个符合要求的偏移量就是1。

对于变量s,类型为short,长度为2,short和有效对齐值二者中的最小值为2,第一个符合要求的地址为5。

到目前为止,使用的空间大小是7,已经满足结构体大小是有效对齐值的整数倍的要求。

MyStruct分布3

例4:

#include <iostream>
#include <emmintrin.h>struct MyStruct {char c;__m128i i;
};int main()
{MyStruct obj;std::cout << "start addr of obj = " << (void*)&obj << std::endl;std::cout << "offset of c = "  << offsetof(MyStruct,c) << std::endl;std::cout << "offset of i = " << offsetof(MyStruct,i) << std::endl;std::cout << "sizeof MyStruct = " << sizeof(MyStruct);
}

执行结果如下:

start addr of obj = 0x7fff9d47cd90
offset of c = 0
offset of i = 16
sizeof MyStruct = 32

首先,结构中最长的数据类型是__m128i,长度为16。因此结构体的有效对齐值是16。

对于c变量而言,没有悬念,将排在0偏移地址处。

对于变量i,类型为__m128i,长度为16,__m128i和有效对齐值的最小值为16,因此i需要排布在2的整数倍上,因此第一个符合要求的偏移量就是16。

MyStruct分布4

例5:

#include <iostream>
#include <emmintrin.h>#pragma pack(8)
struct MyStruct {char c;__m128i i;
};int main()
{MyStruct obj;std::cout << "start addr of obj = " << (void*)&obj << std::endl;std::cout << "offset of c = "  << offsetof(MyStruct,c) << std::endl;std::cout << "offset of i = " << offsetof(MyStruct,i) << std::endl;std::cout << "sizeof MyStruct = " << sizeof(MyStruct);
}

执行结果如下:

start addr of obj = 0x7ffddbec2c40
offset of c = 0
offset of i = 8
sizeof MyStruct = 24

首先#pragma pack设置的对齐值是8,结构中最长的数据类型是__m128i,长度为16。因此结构体的有效对齐值是8。

对于c变量而言,没有悬念,将排在0偏移地址处。

对于变量i,类型为__m128i,长度为16,__m128i和有效对齐值的最小值为8,因此i需要排布在2的整数倍上,因此第一个符合要求的偏移量就是8。

MyStruct分布5

总结

  • 为了高效的访问内存数据,通常需要对内存数据进行对齐。
  • #pragma pack(n)用于设置的对齐有效值,如果设置比结构体的最长成员还大的对齐值将是无效的。

相关文章:

c++中的对齐问题

c中的对齐问题 需要对齐的原因 尽管内存是以字节为单位&#xff0c;但是大部分处理器并不是按字节块来存取内存的.它一般会以双字节,四字节,8字节,16字节甚至32字节为单位来存取内存&#xff0c;我们将上述这些存取单位称为内存存取粒度. 现在考虑4字节存取粒度的处理器取in…...

力扣(LeetCode)算法_C++—— 存在重复元素

给你一个整数数组 nums 。如果任一值在数组中出现 至少两次 &#xff0c;返回 true &#xff1b;如果数组中每个元素互不相同&#xff0c;返回 false 。 示例 1&#xff1a; 输入&#xff1a;nums [1,2,3,1] 输出&#xff1a;true 示例 2&#xff1a; 输入&#xff1a;nums …...

OpenCV实现Photoshop曲线调整

《QT 插件化图像算法研究平台》有仿Photoshop曲线调整图像的功能&#xff0c;包括RGB曲线调整和HSV曲线调整。 Photoshop曲线调整原理&#xff1a;RGB、HSV各通道曲线&#xff0c;可以理解为一个值映射&#xff08;值转换&#xff09;函数。X轴是输入&#xff0c;Y轴是输出。x0…...

【探索Linux】—— 强大的命令行工具 P.8(进程优先级、环境变量)

阅读导航 前言一、进程优先级1. 优先级概念2. Linux查看系统进程3. PRI&#xff08;Priority&#xff09;和NI&#xff08;Nice&#xff09; 二、环境变量1. 概念2. 查看环境变量方法3. 环境变量的组织方式4.通过代码获取环境变量5. 环境变量的特点 总结温馨提示 前言 前面我们…...

蓝牙协议栈BLE

前言 这阵子用到蓝牙比较多&#xff0c;想写一个专栏专门讲解蓝牙协议及其应用&#xff0c;本篇是第一篇文章&#xff0c;讲解低功耗蓝牙和蓝牙协议栈。 参考网上各大神文章&#xff0c;及瑞萨的文章&#xff0c;参考GPT&#xff0c;并且加入了一些本人的理解。 图片部分源自…...

企业架构LNMP学习笔记17

反向代理&#xff1a; 反向代理服务器和真实访问的服务器是在一起的&#xff0c;有关联的。 根据实际业务需求&#xff0c;分发代理页面到不同的解释器。常见于代理后端服务器。 安装apache服务器&#xff1a; yum install -y httpd 修改配置文件&#xff1a; vim /et/http…...

php 获取每月开始结束时间,指定月份的开始结束时间戳

php 获取指定月份的开始结束时间戳。 /** * * 获取指定年月的开始和结束时间戳 * param int $year 年份 * param int $month 月份 * return array(开始时间,结束时间) */ function getMonthBeginAndEnd($year 0, $month 0) {$year $year ? $year : date(Y);$month $month…...

Docker技术入门| Part03:Dockerfile详解(Dockerfile概念、Dockerfile 指令、使用Dockerfile构建镜像)

文章目录 1. Dockerfile概念2. Dockerfile 指令FROM 指定基础镜像RUN执行命令CMD 容器启动命令COPY 复制文件ADD 更高级的复制文件ENV 设置环境变量ARG 构建参数VOLUME 定义匿名卷EXPOSE 暴露端口WORKDIR 指定工作目录USER 指定当前用户LABEL 为镜像添加元数据SHELL 指令 3. 使…...

分享一个有意思的线程相关的程序运行题

翻开之前的代码&#xff0c;发现了一个有意思的代码&#xff0c;猜以下代码的运行结果&#xff1a; package thread;/*** author heyunlin* version 1.0*/ public class ThreadMethodExample {public static void main(String[] args) {Thread thread new Thread(new Runnabl…...

集合的进阶学习

集合体系结构 Collection 单列集合 包含List Set List 包含ArrayList LinkedList Set包含HashSet TreeSet HashSet包含LinkedHashSet List系列集合&#xff1a;添加的元素是有序的、可重复、有索引 Set系列集合&#xff1a;添加的元素是无序的、不重复、无索引 Collectio…...

Java真过饱和了吗?现在学Java迟了?

Java行业内幕揭秘 我是某有名机构的线下课Java老师&#xff0c;负责Java热门框架教学&#xff0c;如Spring、Spring MVC、Spring Boot。但最近被解雇了&#xff0c;让我来吐槽一下。Java现在的学习人数真的太多太多了。 Java的学习饱和度 Java学习的人太多&#xff0c;给你一…...

glibc2.35-通过tls_dtor_list劫持exit执行流程

前言 glibc2.35删除了malloc_hook、free_hook以及realloc_hook&#xff0c;通过劫持这三个hook函数执行system已经不可行了。 传统堆漏洞利用是利用任意地址写改上上述几个hook从而执行system&#xff0c;在移除之后则需要找到同样只需要修改某个地址值并且能够造成程序流劫持…...

linux-OpenSSL升级

1.安装编译所需的安装包 yum install -y gcc make perl zlib-devel 2.从 OpenSSL 官网下载&#xff08;https://www.openssl.org/source/openssl-1.1.1v.tar.gz&#xff09; 注:如果原先版本为1.x.x,升级时还是需要选择1.x.x 3. 编译安装 # 解压tar -xvf openssl-1.1.1v.tar…...

Nginx全家桶配置详解

源码包安装NGINX A&#xff0c;搭建Web Server&#xff0c;任意HTML页面&#xff0c;其8080端口提供Web访问服务&#xff0c;截图成功访问http(s)&#xff1a;//[Server1]:8080并且回显Web页面。保留Server1&#xff0c;但是不允许直接访问Server 1&#xff0c;再部署1套NGINX …...

CMake生成Visual Studio工程

CMake – 生成Visual Studio工程 C/C项目经常使用CMake构建工具。CMake 项目文件&#xff08;例如 CMakeLists.txt&#xff09;可以直接由 Visual Studio 使用。本文要说明的是如何将CMake项目转换到Visual Studio解决方案(.sln)或项目(.vcxproj) 开发环境 为了生成Visual S…...

数学建模--K-means聚类的Python实现

目录 1.算法流程简介 2.1.K-mean算法核心代码 2.2.K-mean算法效果展示 3.1.肘部法算法核心代码 3.2.肘部法算法效果展示 1.算法流程简介 #k-means聚类方法 """ k-means聚类算法流程: 1.K-mean均值聚类的方法就是先随机选择k个对象作为初始聚类中心. 2.这…...

防坠安全带上亚马逊美国站要求的合规标准是什么?

防坠安全带 防坠安全带是一种防护装备&#xff0c;适合工人在高空作业时或在可能发生跌落的无防护边缘行走时穿着。防坠安全带设计用于包裹身体躯干&#xff0c;并将坠落力至少分布到大腿上部、骨盆、胸部和肩部。防坠安全带是固定物体与非固定物体之间的连接物&#xff0c;通…...

PDF转Word的方法分享与注意事项。

PDF和Word是两种常用的文档格式&#xff0c;它们各有优点&#xff0c;适用于不同的场景。然而&#xff0c;有时候我们需要将PDF转换为Word&#xff0c;以便更好地进行编辑和排版。本文将介绍几种常用的PDF转Word的方法&#xff0c;并分享一些注意事项。 一、PDF转Word的方法 使…...

gitlab配置webhook,commit message的时候校验提交的信息

在 GitLab 中配置 Webhook 来调用 Java 接口以校验 commit 信息&#xff0c;是很多公司的一些要求&#xff0c;因为提交信息的规范化是必要的 在 GitLab 项目中进入设置页面。 在左侧导航栏中选择 “Webhooks”&#xff08;Web钩子&#xff09;。 在 Webhooks 页面中点击 “…...

借助CIFAR10模型结构理解卷积神经网络及Sequential的使用

CIFAR10模型搭建 CIFAR10模型结构 0. input : 332x32&#xff0c;3通道32x32的图片 --> 特征图(Feature maps) : 3232x32即经过32个35x5的卷积层&#xff0c;输出尺寸没有变化&#xff08;有x个特征图即有x个卷积核。卷积核的通道数与输入的通道数相等&#xff0c;即35x5&am…...

华为云AI开发平台ModelArts

华为云ModelArts&#xff1a;重塑AI开发流程的“智能引擎”与“创新加速器”&#xff01; 在人工智能浪潮席卷全球的2025年&#xff0c;企业拥抱AI的意愿空前高涨&#xff0c;但技术门槛高、流程复杂、资源投入巨大的现实&#xff0c;却让许多创新构想止步于实验室。数据科学家…...

ES6从入门到精通:前言

ES6简介 ES6&#xff08;ECMAScript 2015&#xff09;是JavaScript语言的重大更新&#xff0c;引入了许多新特性&#xff0c;包括语法糖、新数据类型、模块化支持等&#xff0c;显著提升了开发效率和代码可维护性。 核心知识点概览 变量声明 let 和 const 取代 var&#xf…...

无法与IP建立连接,未能下载VSCode服务器

如题&#xff0c;在远程连接服务器的时候突然遇到了这个提示。 查阅了一圈&#xff0c;发现是VSCode版本自动更新惹的祸&#xff01;&#xff01;&#xff01; 在VSCode的帮助->关于这里发现前几天VSCode自动更新了&#xff0c;我的版本号变成了1.100.3 才导致了远程连接出…...

AtCoder 第409​场初级竞赛 A~E题解

A Conflict 【题目链接】 原题链接&#xff1a;A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串&#xff0c;只有在同时为 o 时输出 Yes 并结束程序&#xff0c;否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...

【第二十一章 SDIO接口(SDIO)】

第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...

苍穹外卖--缓存菜品

1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得&#xff0c;如果用户端访问量比较大&#xff0c;数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据&#xff0c;减少数据库查询操作。 缓存逻辑分析&#xff1a; ①每个分类下的菜品保持一份缓存数据…...

【python异步多线程】异步多线程爬虫代码示例

claude生成的python多线程、异步代码示例&#xff0c;模拟20个网页的爬取&#xff0c;每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程&#xff1a;允许程序同时执行多个任务&#xff0c;提高IO密集型任务&#xff08;如网络请求&#xff09;的效率…...

AspectJ 在 Android 中的完整使用指南

一、环境配置&#xff08;Gradle 7.0 适配&#xff09; 1. 项目级 build.gradle // 注意&#xff1a;沪江插件已停更&#xff0c;推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...

Springboot社区养老保险系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;社区养老保险系统小程序被用户普遍使用&#xff0c;为方…...

二维FDTD算法仿真

二维FDTD算法仿真&#xff0c;并带完全匹配层&#xff0c;输入波形为高斯波、平面波 FDTD_二维/FDTD.zip , 6075 FDTD_二维/FDTD_31.m , 1029 FDTD_二维/FDTD_32.m , 2806 FDTD_二维/FDTD_33.m , 3782 FDTD_二维/FDTD_34.m , 4182 FDTD_二维/FDTD_35.m , 4793...