Linux下C++中的内存对齐

豆包 `src/hotspot/os_cpu/linux_aarch64/os_linux_aarch64.cpp 是OpenJDK中Linux+AArch64平台的底层核心实现文件属于OS_CPU层,是跨平台抽象接口(os/cpu/)的具体实现,衔接JVM核心与底层硬件/操作系统;核心实现线程、原子操作、内存屏障、内存管理、锁、信号处理六大模块,是Java线程、并发、GC的底层基础;重点适配了AArch64的指令集、寄存器、栈对齐、TLS、内存屏障等硬件特性,以及Linux的系统调用、POSIX原语;与X86_64版本的核心差异在于原子操作/内存屏障的指令实现、栈对齐规则、寄存器架构; 阅读详情

  这篇文章主要参考的是网上的一些资料,网上说的是VC环境下的,我在Linux下试了一下,把结果弄上来供大家一起学习之用。

1.首先第一个问题就是为什么要进行对齐,现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特 定的内存地址访问,这就需要各种类型数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放,这就是对齐。 
    对齐的作用和原因:各个硬件平台对存储空间的处理上有很大的不同。一些平台对某些特定类型的数据只能从某些特定地址开始存取。比如有些架构的CPU在访问 一个没有进行对齐的变量的时候会发生错误,那么在这种架构下编程必须保证字节对齐.其他平台可能没有这种情况,但是最常见的是如果不按照适合其平台要求对 数据存放进行对齐,会在存取效率上带来损失。比如有些平台每次读都是从偶地址开始,如果一个int型(假设为32位系统)如果存放在偶地址开始的地方,那 么一个读周期就可以读出这32bit,而如果存放在奇地址开始的地方,就需要2个读周期,并对两次读出的结果的高低字节进行拼凑才能得到该32bit数 据。显然在读取效率上下降很多。

首先考虑下面的一个结构:

class TestClass
{
   private:
	  double da1;
	  char da2;
	  int da3;
};

我们先测试一下double,char,int在我的电脑上占的位数:


那我们再看看TestClass占用的位数:


这说明编译器给我们进行了内存对齐。

规则和vc上是一样的:各成员变量存放的起始地址相对于结构的起始地址的偏移量必须为该变量的类型所占用的字节数的倍数.且结构的大小为结构的字节边界数(即该结构中占用最大空间的类型所占用的字节数)的倍数。

char  
偏移量必须为sizeof(char)即1的倍数.  

int  
偏移量必须为sizeof(int)即4的倍数.  

float  
偏移量必须为sizeof(float)即4的倍数. 

double  
偏移量必须为sizeof(double)即8的倍数.

最开始的时候,偏移为0,刚好是8的倍数,分配8B之后,偏移是8了,是1的倍数。到int的时候偏移是9了,不是4的倍数,所以需要进行字节的对齐。填充3个字节到12,所以最后的结果是16.16刚好是结构体占用空间最大的类型(double)的倍数。

我把三个变量的位置换一下,看看结果:

class TestClass
{
   private:
	  char da1;
	  double da2;
	  int da3;
};

看看结果是多少:


现在变成24了,按照刚才所说的规则,分配完int之后结果是20,但是20不是最大类型(double)的倍数,所以要进行填充,到24.

Linux下也提供了和vc一样的屏蔽默认对齐方式的指令。#pragma pack(n)来设定变量以n字节对齐方式。n字节对齐就是说变量存放的起始地址的偏移量有两种情况:第一、如果n大于等于该变量所占用的字节数,那么偏移量必须满足默认的对齐方式,第二、如果n小于该变量的类型所占用的字节数,那么偏移量为n的倍数,不用满足默认的对齐方式。结构的总大小也有个约束条件,分下面两种情况:如果n大于所有成员变量类型所占用的字节数,那么结构的总大小必须为占用空间最大的变量占用的空间数的倍数;否则必须是n的倍数。

下面是一个例子:

#pragma pack(push)
#pragma pack(4)
using namespace std;
class TestClass
{
   private:
	  char da1;
	  double da2;
	  int da3;
};
#pragma pack(pop)

测试这个Class的大小结果是16B.


最开始给da1分配空间,da1占用的空间小于4,且最开始的偏移是0,满足默认的对齐的方式,给它分配了一个字节,到da2的时候,da2占用的空间是大于4的,所以这个时候的偏移只需要是4的倍数,不像默认的方式必须是8的倍数。填上3个字节,此时的偏移是4了,分配了8个字节。到da3了,da3占用的空间等于4,那需要满足默认的对齐方式,现在的偏移是12了,满足就直接给da3分配空间。大小为16,在看结构体的问题,结构体最大的比4大,所以最后的大小是4的倍数就可以了。

我们把n改成8看看结果:


按照给定的规则分析就可以得到这个结果。



        
LVGL V8.2自定义图标避坑大全:结构体引用+内存对齐实战解析 本文深入解析LVGL V8.2自定义图标开发中的关键技术与常见问题,涵盖结构体引用、内存对齐优化及跨平台适配等核心内容。通过实战案例和详细代码示例,帮助开发者规避嵌入式GUI开发中的常见陷阱,提升图标显示性能与稳定性。 阅读详情

相关推荐

使用CLion在Window端进行linux开发

        以往不管是开发x86端linux程序还是arm端linux程序,都是使用Source Insight作为源码编辑工具的,如下图      去年底,发现CLion的2018.3更新版本,可以支持remote host开发了,大爱!     我是基于以下几点原因,将开发工具换成CLion 1. 语法高亮较明显、跳转、重构方便(我很看重这个); 2. 可以使用图形界面进行调...

alist的笔记专栏 1万+

Linux C/C++编程——常用关键字pragma pack和attribute_packed总结

(一)pragma pack使用说明 用sizeof运算符求算某结构体所占空间时,并不是简单地将结构体中所有元素各自占的空间相加,这里涉及到内存字节对齐的问题,有时候为了内存对齐需要补齐空字节。通常写程序的时候,不需要考虑对齐问题。编译器会替我们选择适合目标平台的对齐策略。当然,我们也可以通知给编译器传递预编译指令而改变对指定数据的对齐方法。 语法:#pragma pack( [show] | [push | pop] [, identifier], n ) #pragma pack() 能够取消自定义的对

汽车网络那些事儿 2489

避坑指南:STM32CubeMX安装后,你的第一个工程为什么中文全是乱码?

本文详细解析了STM32CubeMX安装后中文乱码问题的根源及解决方案。从诊断乱码现象到分析编码冲突背景,提供了新项目UTF-8化、旧项目GBK兼容及版本降级等多种实用方案,帮助开发者彻底解决这一常见问题。

weixin_30699955的博客 474

linux c/c++常用关键字pragma pack和attribute_packed总结

(一)pragma pack使用说明 用sizeof运算符求算某结构体所占空间时,并不是简单地将结构体中所有元素各自占的空间相加,这里涉及到内存字节对齐的问题,有时候为了内存对齐需要补齐空字节。通常写程序的时候,不需要考虑对齐问题。编译器会替我们选择适合目标平台的对齐策略。当然,我们也可以通知给编译器传递预编译指令而改变对指定数据的对齐方法。 语法:#pragma pack( [show] | [...

陌上花开缓缓归以的博客 1798

【中文OCR】中文字符图片的分割方法

最近想做一个关于中文OCR的小系列,也是对之前做的东西的一个总结。作为这个系列的第一篇,我觉得还是有必要说一下关于中文字符图片分割的问题。因为现在开源的OCR代码比较多,相对而言对字符图片的分割的方法提的比较少,尤其是中文字符图片的分割还是有一定困难在里面的。 一、普遍使用的切割方法 现在大部分开源项目上用切割方法还是基于水平、垂直投影字符切割方法。 原理比较简单容易理解,也比较容易实现。先...

zhangzm0128 1万+

告别蓝牙音质妥协:用ESP32和PCM5102搭建WiFi无损音频播放器(附完整代码)

本文详细介绍了如何利用ESP32微控制器和PCM5102 DAC芯片构建一套完整的WiFi无损音频流媒体系统,彻底摆脱蓝牙协议的音质束缚。从硬件原理到软件实现,包括核心器件选型、电路设计、I2S音频驱动实现以及系统优化方案,帮助音频发烧友实现高保真无线音频传输。

weixin_30733003的博客 542

Linux __attribute__((aligned(n)))和#pragma pack

目录字节对齐1. 什么是字节对齐2. 字节对齐作用C语言中字节对齐1. __attribute__关键字2. pragma pack代码案例__attribute__扩展1. 函数属性2. 变量属性3. 类型属性 字节对齐 1. 什么是字节对齐   在C语言中,数据结构是一种复合的数据类型,其构成元素既可以是基本的数据类型(例如,int、long、char、bool等)的变量,也可以是复合数据类型(例如,数组、链表、数据结构等)的数据单元。在数据结构中,编译器为其每个成员按照正常边界进行空间分配。各个成员按

CFH1021的博客 1710

5分钟搞懂异构图注意力网络(HAN):从元路径到节点聚合的全流程解析

本文深入解析异构图注意力网络(HAN)的核心原理与实战应用,从元路径设计到多级注意力实现的全流程。HAN通过节点级和语义级双重注意力机制,有效处理包含多种节点和边类型的异构图数据,在电商推荐、学术网络分析等场景展现卓越性能。文章提供DGL实现代码和调参技巧,帮助开发者快速掌握这一强大工具。

weixin_29056701的博客 311

linuxc/c++内存对齐

为什么要内存对齐? 尽管内存是以字节为单位,但是大部分处理器并不是按字节块来存取内存的.它一般会以双字节,四字节,8字节,16字节甚至32字节为单位来存取内存。 现在考虑4字节存取粒度的处理器取int类型变量(32位系统),该处理器只能从地址为4的倍数的内存开始读取数据。假如没有内存对齐机制,数据可以任意存放,现在一个int变量存放在从地址1开始的联系四个字节地址中,该处理器去取数据时,要先从0地址开始读取第一个4字节块,剔除不想要的字节(0地址),然后从地址4开始读取下一个4字节块,同样剔除不要的数据(5

pipi糖的博客 338

比亚迪 10C 闪充技术全解析:超高速离子通道与双电子流设计如何颠覆电动车补能格局?

性能碾压主流方案参数宁德时代6C比亚迪10C优势幅度最大电流700A1000A+43%内阻降幅30%50%+67%5分钟补能240公里400公里+67%

百态·数智思维 | 聚焦大数据、量化与未来AI 1122

2026年全国青少年信息素养大赛复赛真题(算法应用主题赛C++初中组:带解析)(7月4日试卷一)【文末附答案和解析】

2026年全国青少年信息素养大赛复赛真题(算法应用主题赛C++初中组:带解析)(7月4日试卷一)【文末附答案和解析】

王老师青少年编程 1736

64位和32位平台下C/C++结构内存对齐

1. 在 64 位 Linux 下,结构体字段默认按 8 字节对齐;32 位 Linux 下,默认 4 字节对齐。 2. 显示指定对齐方式时,会受到机器字长的约束,即 64 位 Linux 下可以按 8 字节及以下的任意字节对齐,32 位只能按 4 字节及以下任意字节对齐。 #include #pragma pack(4) struct Test { char c; long long

码农 6430

地球引擎初级教程:Python API 的安装和介绍

地球引擎的 Python API 提供了许多功能和工具,用于访问和处理地理空间数据。连接到地球引擎在编写地球引擎的 Python 脚本时,首先需要连接到地球引擎服务器。import ee # 初始化地球引擎 ee . Initialize()这将初始化地球引擎并建立与服务器的连接。加载和显示图像使用地球引擎的 Python API,您可以加载和显示卫星图像。import ee# 初始化地球引擎# 加载 Landsat 8 影像# 显示影像print('影像 URL:', url)

UePostscript的博客 1007

浅谈C++内存管理

1.从内存对齐讲起 对于结构体变量内存对齐遵循以下三个原则: 变量的起始地址能够被其对齐值整除,结构体变量的对齐值为最宽的成员大小。 结构体每个成员相对于起始地址的偏移能够被其自身对齐值整除,如果不能则在前一个成员后面补充字节。 结构体总体大小能够被最宽的成员的大小整除,如不能则在后面补充字节。 此外还有编译器的默认对齐值,一般默认对齐值为4(结构体的实际对齐值会取结构体对齐值和编译器默认对齐值中较小的那一个)。 那么为什么要内存对齐? 为了减少使用的内存 为了提升数据

森森猪的博客 327

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

Linux C/C++内存越界定位: 利用mprotect使程序在crash在第一现场

原文链接:https://blog.youkuaiyun.com/thisinnocence/article/details/80025064 对于大型Linux C/C++程序,内存越界和野指针类问题往往比较难定位。有的由于内存被非法改写造成了业务功能问题,有的则直接导致了程序crash,而且还经常不是第一现场。针对这种问题,可以采取的解决方法有: 利用valgrind工具来排查,会影响程序性能; 使用Address Sanitizer工具排查; 如果是固定的内存被破坏,可以利用gdb watch来抓取第一现

segments的专栏 616

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

C++字节基础

bool am_little_endian () { unsigned short i=1; return (int)*((char *)(&i)) ? true : false; } int main() { if(am_little_endian()) { printf(“本机字节序为小段序!\n”); }else { printf(“本机字节序为大段序!\n”); } return 0; }

asdasfdgdhh的博客 570

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

linux中内存泄漏的检测(四)记录泄漏的大小

《linux中内存泄漏的检测(三)定制化的new/delete》讲到,利用C++的函数重载的特性,使C++的代码,也能方便地为new/delete加上用于检测内存泄漏的统计代码。然而,也因此引入的新的问题。目前的统计方式仅仅统计申请/释放内存的次数,并没有统计每次申请/释放内存的大小。 这种方法对于C来说是够用了,因为在C中申请和释放的大小是相同的,而在C++中就不一定了。 考虑以下两种情况:(

幸福在路上 4540

C++类内存布局深度解析:pahole工具实战指南

在C++程序开发中,理解对象在内存中的实际布局是进行性能优化和问题排查的关键。内存对齐机制决定了数据成员在内存中的排列方式,编译器会根据平台特性自动插入填充字节以满足对齐要求,这直接影响内存使用效率和访问性能。掌握内存布局原理对于开发内存敏感型应用如高频交易系统和嵌入式软件至关重要,它能帮助开发者发现潜在的内存浪费和访问效率瓶颈。通过分析DWARF调试信息,pahole工具能够可视化展示C++类的完整内存结构,包括成员偏移、填充字节和虚函数表指针等细节。这项技术特别适用于优化密集存储对象的内存占用、排查跨模

weixin_30402231的博客 18

浅谈c++内存管理

1.从内存对齐讲起 对于结构体变量内存对齐遵循以下三个原则: 1.变量的起始地址能够被其对齐值整除,结构体变量的对齐值为最宽的成员大小。 2.结构体每个成员相对于起始地址的偏移能够被其自身对齐值整除,如果不能则在前一个成员后面补充字节。 3.结构体总体大小能够被最宽的成员的大小整除,如不能则在后面补充字节。 此外还有编译器的默认对齐值,一般默认对齐值为4(结构体的实际对齐值会取结构体对齐...

1万+

C++ 内存对齐

a. 基本类型:所有的基本类型都有相应的对齐参数,编译器在编译时,会用全局的对齐参数和当前类型的对齐参数中较小的一个进行对齐。比如,编译时指定暗8bytes对齐(用#pragma pack(8)实现之),可是由于一个char变量的大小为一个byte,所以最后还是按1byte对齐。 b. 复合类型:复合类型的对齐原则,就是取其成员变量数据类型的字节数的最大者和在编译时指定的对齐数两者之间较小的字节

chlele0105的专栏 942

C++中struct内存对齐

在C和C++中,编译器会根据目标平台的要求对数据进行内存对齐,以提高内存访问效率。内存对齐是指数据存储的地址必须是某个值(通常是数据类型大小的倍数)的整数倍。需要注意的是,修改对齐方式可能会影响内存访问效率,因为非对齐的内存访问可能会比对齐的内存访问慢。编译器会根据特定的规则在结构体成员之间插入填充字节,以确保每个成员都能从其数据类型的自然边界开始存储。同样,为了保证结构体的大小是其成员中最大对齐要求的倍数,编译器会在。的大小将是6字节,而不是默认对齐方式下的12字节。将对齐方式设置为1字节,

m0_74079831的博客 428

面试必问!Linux 下 C/C++ 内存对齐深度解析:从底层原理到实战避坑

【摘要】本文深入解析Linux C/C++开发中的内存对齐机制。通过类比超市货架与CPU访问习惯,揭示内存对齐的本质是优化数据排列以减少CPU访问次数。文章从硬件限制、性能优化和缓存利用三个层面剖析对齐的必要性,详细讲解C/C++的4条核心对齐规则,并通过6个代码示例演示结构体成员排列对内存占用的影响。同时介绍GCC的aligned/packed属性实现对齐控制,提供性能测试数据(非对齐访问耗时是对齐的2倍),并解析3道典型面试题。最后强调对齐优化原则:按成员对齐系数从小到大排列可显著减少填充字节

C++、Python、Linux、人工智能、车载开发、QT开发、AI绘画。 1428

64位linux默认内存对齐,memory_align

8种机械键盘轴体对比本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选?关于C/C++中结构体(类)内存对齐问题各种笔试面试都会涉及的问题,具体的可以查阅相关标准(如C99,C11等)或者翻阅国外知名论坛stackoverflow等寻找相关资料进一步分析,我个人的一些总结如下,如有不对之处,还请诸位不吝赐教.1. 首先放出现代PC编译器在实现的时候对于字长的一些典型约定:32位编译器:cha...

weixin_31966615的博客 859

内存按页对齐

1.定义内存页大小为4kb #define TEST_SYSTEM_PAGE_SIZE 4096 2.设置内存按页对齐 ​ int test_size = 128; struct v4l2_buffer buf; buf.length = ((test_size + TEST_SYSTEM_PAGE_SIZE - 1) & (~(TEST_SYSTEM_PAGE_SIZE - ...

weixin_43071994的博客 2432

C/C++内存对齐

1、什么是内存对齐 还是用一个例子带出这个问题,看下面的小程序,理论上,32位系统下,int占4byte,char占一个byte,那么将它们放到一个结构体中应该占4+1=5byte;但是实际上,通过运行程序得到的结果是8 byte,这就是内存对齐所导致的。 //32位系统 #include<stdio.h> struct{ int x; char y; }s; int main() { printf("%d\n",sizeof(s); // 输出8 retur

weixin_42684313的博客 199
上一篇: C++中引用和指针的区别
下一篇: Vim函数自动补齐(包括库函数)
Virgilio
博客等级 码龄17年 33粉丝 22原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值