变量的内存分配:内存对齐

内存对齐与内存分配原则 首先讲一个概念—-内存对齐一种提高内存访问速度的策略,cpu在访问未对其的内存需要经过两次内存访问,而经过内存对齐一次就可以了。(?)打个比方就是:操作系统在访问内存时,每次读取一定的长度(这个长度是系统默认的对其系数),程序中你也可以自己设定对齐系数,告诉编译器你想怎么对齐,可用#pargam pack(n),指定n为对其系数。但是当没有了内存对齐,cpu在访问一个变量时候,可能会访问两次,为什么 阅读详情

数据结构还有变量等等都需要占有内存,在很多系统中,它都要求内存分配的时候要对齐,这样做的好处就是可以提高访问内存的速度。
#include <iostream>
 2 using namespace std;
 3 
 4 struct X1
 5 {
 6   int i;//4个字节
 7   char c1;//1个字节
 8   char c2;//1个字节
 9 };
10 
11 struct X2
12 {
13   char c1;//1个字节
14   int i;//4个字节
15   char c2;//1个字节
16 };
17 
18 struct X3
19 {
20   char c1;//1个字节
21   char c2;//1个字节
22   int i;//4个字节
23 };
24 int main()
25 {   
26     cout<<"long "<<sizeof(long)<<"/n";
27     cout<<"float "<<sizeof(float)<<"/n";
28     cout<<"int "<<sizeof(int)<<"/n";
29     cout<<"char "<<sizeof(char)<<"/n";
30 
31     X1 x1;
32     X2 x2;
33     X3 x3;
34     cout<<"x1 的大小 "<<sizeof(x1)<<"/n";
35     cout<<"x2 的大小 "<<sizeof(x2)<<"/n";
36     cout<<"x3 的大小 "<<sizeof(x3)<<"/n";
37     return 0;
38 }

 

输出的结果:

 

1 long 4
2 float 4
3 int 4
4 char 1
5 x1 的大小 8
6 x2 的大小 12
7 x3 的大小 8

 

http://www.cppblog.com/cc/archive/2007/09/17/10765.html

 

在定义结构体x1,x2,x3时,由于变量的顺序不同,而导致分配的内存不同

内存是一个连续的块, 以每4个字节为一个对齐单位,来看一下x1,x2,x3在内存中的布局

对于x1,第一个是int型,它占4个字节,所以前面4格就满了,第二个是char型,它占第二个4字节组块的第一格,第三个是char型,它占第二个4字节组块的第二格,因为有内存对齐,所以输出结果为8而不是6.

对于x2,第一个类型是char型,它占用一个字节,所以它首先排在第一组块的第一个格子里面,第二个是Int类型,它占用4个字节,第一组块已经用掉一格,还剩3格,肯定是无法放下第二Int类型的,因为要考虑到对齐,所以不得不把它放到第二个组块,第三个类型是Char类型,跟第一个类似。所因为有内存分块对齐,我们的内存就不是8个格子了,而是12个了

 

 

当数组作为函数的参数传递时,该数组自动退化为同类型的指针。

如void Funct(char a[100])

{

   cout<<sizeof(a)<<endl;//输出结果为4

}

 

 

 而对于

struct

{

char a;

double b;

char c;

}

这里内存默认对齐字节数是8字节,所以结构体所占的字节数是24.

 

 

深入理解字节对齐:

 

结构体是种复合数据类型,其成员由基本数据类型构成(short,int,long,float,double,char),也可以是复合数据类型的数据单元(数组,联合,结构等),编译器为结构的每个成员按自然边界分配空间 ,各个成员按照它们被声明的顺序在内存中顺序存储,为了使cpu对变量加快访问,变量的起始地址应该具有某种特性,即所谓的对齐,如4字节的int型,其起始地址应该位于4字节的边界上,即能够被4整除。

 

字节对齐的作用:便于cpu快速访问,利用字节对齐合理的节省存储空间

对于32位机器来说,4字节对齐能够使cpu的访问速度提高,如果跨越了4字节边界存储,那么cpu就要读取2次,效率降低了。如果在32bit中使用1字节或2字节对齐,反而使处理器 速度降低了。所以要考虑处理器的类型。另外,也要考虑 编译器的类型,vc,gcc默认都是4字节对齐

 

更改c编译器的缺省字节对齐方式:

缺省条件下,c编译器为每个变量或数据单元按自然边界条件分配空间

1.使用伪指令:#program pack(n)//c编译器按n个字节对齐

                   #program pack()//取消自定义字节对齐方式

2._attribute(alligned(n)),//让所有的结构成员对齐在n字节的自然边界上,如果结构中有 成员的长  度大于n,则按最大成员的长度来对齐

  _attribute_((packed)),//取消编译过程的优化对齐,按实际占用字节数对齐。

 

举例说明:

struct

{

    char a;

    short b;

    float   c;

    char d;

}

 

编译器默认情况下对结构体做自然边界对齐,结构的第一个成员a,其偏移地址为0,占用 1个字节,第二个成员为b,其起始地址必须2字节对界。因此编译器在a和b之间填充一个空字节,结构的第3个成员和第4个成员恰好落在自然边界上,在结构中,第3个成员c要求4字节对齐,为该结构中所有成员要求的最大边界单元,因而该结构的自然边界对界条件是4字节,整个结构所占空间为12字节

 

如添加#program pack(1),整个结构所占字节为8字节

        #program pack (2),。。。。。。。。。10字节

 

32位机器上各个基本数据类型所占的长度:

char  1 (有符号无符号相同)

short 2 (有符号无符号相同)

int    4 (有符号无符号相同)

long  4 (有符号无符号相同)

float  4

double  8

 

 

编译器按什么样的原则对齐:

 

首先看一下4个基本概念,

1.数据自身对齐值:char 1,short 2,int long float 4

2.结构体或类的自身对齐值:其成员中自身对齐值最大的那个

3.指定对齐值:#program pack(value) 对齐值为value

4.数据成员,结构体和类的有效对齐值:自身对齐值和指定对齐值中小的那个

 

有效对齐值N是最终决定数据存储方式的值。有效对齐N,表示“对齐在N上”,也就是说该数据的起始地址%N=0.而数据结构中的数据变量都是按定义的顺序来排放的,结构体的成员要对齐,结构题本身也要根据自身的对齐值圆整(就是结构体成员所占的总长度是结构体有效对齐值的整数倍)

 

 

 

基于溶解气体分析(DGA)的变压器DGA数据故障诊断含代码含数据 在拥有可靠的DGA数据的前提下,结合机器学习分类算法,可以实现变压器的故障诊断。在此数据集的基础上,用随机森林跑出的结果如图。 阅读详情

相关推荐

YOLOv11多模态融合实战:基于YOLOFuse的RGB与红外线(IR)协同检测技术解析

本文深入解析了YOLOv11多模态融合技术,重点介绍基于YOLOFuse框架的RGB与红外线(IR)协同检测方法。通过动态权重分配、跨模态特征对齐等创新设计,实现在低光照等复杂环境下的高精度目标检测,mAP提升高达37%。文章包含实战案例、训练技巧和部署方案,为计算机视觉开发者提供完整的多模态融合解决方案。

weixin_29038345的博客 290

C语言中 #pragma pack()

/******************************************************************** #pragma pack(show) //显示当前内存对齐的字节数,编辑器默认8字节对齐 #pragma pack(n) //设置编辑器按照n个字节对齐,n可以取值1,2,4,8,16 #pragma pack(push) ...

随喜读书会的博客 1734

Ubuntu22.04安装搜狗输入法踩坑实录:从依赖报错到完美解决的完整指南

本文详细解析了在Ubuntu 22.04系统上安装搜狗拼音输入法的完整流程,从解决依赖报错到配置fcitx框架,再到最终优化使用体验。针对常见的dpkg安装错误和fcitx冲突问题,提供了实用的解决方案和命令,帮助用户顺利完成安装并享受流畅的中文输入体验。

palm99的专栏 971

波奇学c:结构体和位段

结构体和位段,结构体声明,指针,大小,对齐数规则;位段声明,大小

Boki 333

LTR-390UV-01对比VEML6075:5个真实项目中的选型避坑指南

本文对比了LTR-390UV-01和VEML6075两款环境光传感器在5个真实项目中的表现,提供了选型避坑指南。通过智能手环、农业温室、紫外线消毒柜等场景的实测数据,分析了动态范围、抗干扰性、温度稳定性等关键差异,帮助开发者在成本与性能间做出最优选择。

weixin_28733777的博客 219

[QMT量化交易小白入门]-二十八、有了回测年化收益好的策略,如何在QMT量化实盘呢(附python代码解析)

本专栏主要是介绍QMT的基础用法,常见函数,写策略的方法,也会分享一些量化交易的思路,大概会写100篇左右。QMT的相关资料较少,在使用过程中不断的摸索,遇到了一些问题,记录下来和大家一起沟通,共同进步,自己淋过雨了,希望大家都有一把伞。

木头大左的博客 2924

结构体内存对齐之对齐规则

1.如果没有内存对齐,有些数据可能要CPU的二次访问才能取到,因为CPU都是按照块来取数据的 #program pack(show) -- 用于查看当前对齐模数,默认是8 #program pack(1) -- 可以修改对齐模数,必须是2的n次方 2.如果采用默认对齐模数,则结构体内存对齐,内部对齐规则如下: 1)从第一个属性开始,偏移量为0 2)从第二个属性开始计算偏移,要放在 该类...

JCjunior的博客 1279

利用Python爬虫采集京东商品评论情感分析案例(含完整代码)

在电商蓬勃发展的今天,商品评论蕴含着巨大的商业价值。本文以京东商品评论为研究对象,系统介绍如何使用Python构建一个完整的评论采集与情感分析系统。文章涵盖京东反爬机制分析、动态请求模拟、评论数据解析、中文文本预处理、基于SnowNLP和深度学习的情感极性分类、以及可视化展示等完整技术链路。所有代码均基于2025-2026年最新可用接口编写,并提供可直接运行的完整源码。全文力求详实,总字数逾八千字,适合Python数据分析从业者、电商运营人员及自然语言处理初学者参考实践。目录摘要第一章 引言。

2201_76125261的博客 88

#pragma pack()的作用

今天有同事问我#pragma pack(1)是干嘛的,之前没用过,遂百度。 原来这东西是用来指定内存对齐方式的。 我们知道,定义一个struct的时候,其默认分配空间为4的倍数。但是用#pragma pack(1)之后,其分配的空间就是1的倍数了,也就是网上说的内存连续。 举个例子: Struct A { char a; double b; }; 这个时候我去查看Struct A的sizeof,会发现值为16,这是因为内存对齐(如果不知道为啥是16,可以百度下内存对齐机制)。

whr19970424的博客 557

Vue2 - 最新详细实现接入天地图详细配置流程及示例代码教程,提供获取用户当前定位的城市名称及省市区数据、精准经纬度信息、IP属地定位、地图搜索标点等示例,解决天地图跨域报错/页面白屏/定位不准问题

vue2,nuxt2,天地图,使用教程,vue接入国家天地图,定位api,ip属地定位,获取用户当前位置数据,省市区,地图不显示,白屏,报错,vue2如何使用天地图,地图选点,cors跨域,白名单设置了还是不行,vue项目调用天地图api实现定位,Vue2中使用天地图,详细教程,天地图申请密钥key教程,经纬度,经纬度不准确,一直定位北京,定位在北京不准怎么办,nuxt项目天地图,网站,网页,h5页面,地图显示不全,获取当前定位,如何使用天地图,拿到客户ip地址定位城市名称,距离计算,实时搜索地址逆解析,天

🏆 前端领域优质创作者 5324

杰理SDK入门教程(五):按键使用配置

摘要 杰理SDK提供IO按键和AD按键两种方案。IO按键通过GPIO电平检测实现,配置时需要设置板级宏定义和硬件连接,默认使用PB1引脚。AD按键基于ADC电压采样,通过电阻分压区分按键,需配置功能使能、硬件通道和键值适配。按键功能通过修改SDK中的key_table文件实现。两种方案适用于不同硬件场景,开发者可根据需求选择。

qq_42014563的博客 775

#pragma pack(1) 的意义是什么

设置结构体的边界对齐为1个字节,也就是所有数据在内存中是连续存储的。 比如你在C语言中定义下面这样的结构体: struct s { char ch; int i; }; 然后在主函数中写一句:printf("%d", sizeof(struct s)) 也就是输出结构体s所占的字节数 你觉得输出结果会是多少呢? 我们知道,char型占用1个字节,int型占4个字节,那么输出的结果是5吗

xiao156520的专栏 5606

OPTEE:TA命令操作的实现(三)

上文我们创建好了通道,现在就是操作,怎么操作TA呢?REE侧的CA执行创建会话操作成功后,CA就可使用获取到的调用来让TA执行特定的命令。通过ioctl的系统调用发送到OP-TEE的驱动中,保存在共享内存中,并触发安全监控模式调用(smc)切换到Monitor模式(ARMv7)或EL3(ARMv8)中进行安全世界状态的处理。

叫好与叫座虽然不是对立面,但想在同一个作品中达到双重效果很难。 1268

变量的内存分配:内存对齐 .

数据结构还有变量等等都需要占有内存,在很多系统中,它都要求内存分配的时候要对齐,这样做的好处就是可以提高访问内存的速度。 #include   2 using namespace std;  3   4 struct X1  5 {  6   int i;//4个字节  7   char c1;//1个字节  8   char c2;//1个字节  9 }; 10  11 s

xiaoaide01的专栏 862

最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版

Part-E1-SDIO-Specification-Ver4.00-Final-120220.pdf:最新的sdio 4.0 spec 协议标准 带书签 高清完整PDF版,包括SDIO 接口的外设,SDIO 接口官方协议等。

蓝牙模块HM-10手册

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

结构体内存分配

4:long int 在32位平台下,4 字节对齐,即存放long int 型的变量,起始内存单元的编号是 4。2:short int 2字节对齐,即存放short int 型的变量,起始内存单元的编号是 2的倍数即可。5:foat 4 字节对齐,即存放foat 型的变量,起始内存单元的编号是4 的倍数即可。3:int 4 字节对齐,即存放int 型的变量,起始内存单元的编号是 4 的倍数即可。1:char 1字节对齐,即存放char 型的变量,内存单元的编号是 1的倍数即可。辟内存的字节单位也不同。

m0_74754000的博客 939

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

c++内存对齐

一.计算struct的size有两个原则:#pragma pack(n) n是编译器的对齐字节数(1)struct中各成员按照对齐原则:在为当前变量(设为a)分配内存时,要参考之前所有变量的偏移量之和(设为d),d必须是min(n,sizeof(a))的倍数,否则编译器会自动在最后补上缺少的字节数。(2)待所有变量都分配完毕之后,还要比较当前所占内存(设为c)与struct中长度最大的变量的长度(

jimlee070128的专栏 894

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

内存对齐原则

内存对齐,是为了方便计算机去读写数据,对齐的地址一般都是 n(n = 2、4、8)的倍数。

pikeNotes的博客 546

c语言内存四区,详解C语言中的内存四区模型及结构体对内存的使用

内存四区1、代码区代码区code,程序被操作系统加载到内存的时候,所有的可执行代码都加载到代码区,也叫代码段,这块内存是不可以在运行期间修改的。2、静态区所有的全局变量以及程序中的静态变量都存储到静态区。3、栈区栈stack是一种先进后出的内存结构,所有的自动变量,函数的形参都是由编译器自动放出栈中,当一个自动变量超出其作用域时,自动从栈中弹出。对于自动变量,什么时候入栈,什么时候出栈,是不需要程...

weixin_30856775的博客 330

内存管理的粗浅认识

1. 全局变量,静态变量,char*分配的内存从静态存储区域获得。 2. 局部变量所需的内存是从栈上分配,不同系统的内存管理器会分配不同的大小,有些为2M,有些是4M,还有其他的。虽然分配的空间比较小,但栈内存分配运算内置于处理器的指令集中,效率很高。出了局部函数后自动释放,较

eckael的专栏 485

关于for循环的局部变量的内存地址问题

环境: windows10 + vs2015 参考网址: https://www.zhihu.com/question/377776789 近日在测试的时候,执行了如下的代码: for (size_t i = 0; i < 100; i++) { int kkk = i; cout << &kkk << endl; } 按照个人本来的想法,局部变量每次都会创建,然后销毁, 那么内存地址应该是每次都不一样的. 但是实际上输出得到地址都是一样的. 在上述网

xiaohongmao663832的博客 579

CubeMX配置串口DMA必看:3种内存分配方式对比(全局/静态/动态)及避坑指南

本文详细解析了CubeMX配置STM32串口DMA时的三种内存分配策略(全局变量、静态变量、动态分配),重点探讨了HAL_UART_Transmit_DMA的使用注意事项和避坑指南。通过对比分析不同内存类型的生命周期和适用场景,帮助开发者优化DMA通信性能,避免数据异常等常见问题。

ik6789012的博客 206

结构体变量内存分配问题

由于系统 遵守两个原则 1.为结构体变量的成员变量分配内存的起始地址必须为成员变量内存长度的整数倍。 2.结构体变量内存的总大小必须为sizeof(结构体成员变量)(最大的)的整数倍。 struct Demo{ char a;//sizeof(char)=1 int b;//sizeof(int)=4 flloat c;//sizeof(float)=4 double d;//sizeof...

123向前走的博客 4675

C语言-struct 结构体变量的内存分配

struct内存分配 定义技巧 首先我们定义struct变量,笔者习惯定义时,直接输入: struct name { }; 再对struct内部成员进行定义,防止“;”遗漏,导致程序报错。 先看一段代码 #include<stdio.h> struct A { char a; short b; int c; }; struct B { int c; short a; cha...

weixin_41453492的博客 9223

C++ 内存分配与内存对齐

一、C++程序内存分配 C/C++程序编译时内存分为5大存储区 栈区,由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。通俗来讲就是函 数中的变量参数等等,即{}中的内容。 堆区,一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方 式倒是类似于链表。通俗讲就是动态内存分配, 全局区(静态区),—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域(RW),

个人技术博客 2786

内存分配和对齐

/ 早年间的一些 CPU 是不支持没有对齐的内存访问的,但是在现代 CPU 上已经没有了这个问题,编译器也提供了一些选项可以让我们明确指出不需要内存对齐。当一个内存块被释放后,内存分配器会检查相邻的内存块是否也是空闲的。如果是,分配器可能会将这些内存块合并成一个更大的块,减少碎片化,提升内存分配效率。2、每个变量相对于起始位置的偏移量必须是该变量类型大小的整数倍,不是整数倍空出内存,直到偏移量是整数倍为止。内存分配器管理堆上的内存块。大的块被分配后会分割多余的小的块,小的块释放后就合并成大的块。

m0_62494327的博客 1236

C语言基础 -- 结构体变量及其成员内存分配

对于不了解结构体的同学,首先需要搞清楚两个概念:一是结构体类型、二是结构体变量。结构体类型类似与我们知道数据类型(例如:int)是用来声明变量的,它同时规定了该类型的变量所应占用的内存的大小。结构体变量是一个实实在在的变量,它在内存中有地址,并且占用了由声明它时用到的结构体类型所规定的内存大小。请对比下面两个例子:int N;return 0;例1中,int是数据类型,int规定了用它声明的变量的内存大小,即sizeof(int)。N是变量,它有地址,即&N;

LCCprogrammer 2418
上一篇: QT中自定义事件
下一篇: 变量的内存分配
ToSoftWare
博客等级 码龄16年 16粉丝 23原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值