关于内存对齐问题(一)

结构体内存对齐规则 一个结构体变量定义完之后,其在内存中的存储并不等于其所包含元素的大小之和。 #include <iostream> using namespace std; struct A { char a; int b; double c; }; struct B { char a; double c; int b; }; int main() { cou... 阅读详情

http://patmusing.blog.163.com/blog/static/13583496020100143952257/


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

b. 复合类型:复合类型的对齐原则,就是取其成员变量数据类型的字节数的最大者和在编译时指定的对齐数两者之间较小的字节数进行对齐。如果没有用诸如#pragma pack指定全局对齐数,则该复合类型的对齐数就是其成员变量数据类型字节数之最大者。

#include <iostream>

using namespace std;

// #pragma pack(4)

class PatClass0       // PatClass0的对齐数为1。因为其成员变量c1的数据类型为char,而sizeof(char)=1

{

private:

         char c1;

};

 

class PatClass1       // PatClass1的对齐数为1。因为其成员变量c1和c2的数据类型均为char,而sizeof(char)=1

{

private:

         char c1;

         char c2;

};

 

class PatClass2       // PatClass2的对齐数为2。因为其成员变量c1的数据类型均为char,sizeof(char)=1,

{                                    // 成员变量c2的数据类型为short,而sizeof(short)=2。

private:                        // 取其字节数最大者,即2。

         char c1;

         short c2;

};

 

class PatClass3       // PatClass3的对齐数为4。因为其成员变量c1的数据类型均为char,sizeof(char)=1,

{                                    // 成员变量c2的数据类型为int,而sizeof(int)=4。

private:                        // 取其字节数最大者,即4。

         char c1;

         int c2;

};

 

class PatClass4       // PatClass4的对齐数为8。因为其成员变量c1的数据类型均为char,sizeof(char)=1,

{                                    // 成员变量c2的数据类型为double,而sizeof(8)=8。

private:                        // 取其字节数最大者,即8。

         char c1;

         double c2;

};

 

class PatClass5       // PatClass5的对齐数为4。见PatClass3说明

{

private:

         int c1;

};

 

class PatClass6 : public PatClass5 // PatClass6的对齐数为4。这是因为它继承了PatClass5,PatClass5中的成员

{                                                                // 变量c1也会被编译器安插在类PatClass6的对象中(尽管不能对其进行普通意

private:                                                    // 义上的访问),而c1的数据类型为int,sizeof(int)=4。所以PatClass6的对齐数

         char c2;                                          // 为4。

};

 

int main(void)

{

         PatClass0 c0;

         PatClass1 c1;

         PatClass2 c2;

         PatClass3 c3;

         PatClass4 c4;

         PatClass5 c5;

         PatClass6 c6;

 

         cout << "the size of PatClass0 object is: " << sizeof(c0) << endl;

         // PatClass0的对齐数为1byte,它只有一个成员变量char c1,因此其对象c0的大小为1byte

 

         cout << "the size of PatClass1 object is: " << sizeof(c1) << endl;

         // PatClass1的对齐数为1byte,它有两个成员变量char c1和char c2,因此其对象c1的大小为2bytes

 

         cout << "the size of PatClass2 object is: " << sizeof(c2) << endl;

         // PatClass2的对齐数为2bytes,它有一个成员变量char c1和一个成员变量short c2,合起来为3bytes,由于其

// 对齐数为2bytes,因此需要填充1byte,才能变成2的倍数。故此其对象c2的大小为4bytes。

 

         cout << "the size of PatClass3 object is: " << sizeof(c3) << endl;

         // PatClass3的对齐数为4bytes,它有一个成员变量char c1和一个成员变量int c2,合起来为5bytes,由于其

// 对齐数为4bytes,因此需要填充3bytes,才能变成4的倍数。故此其对象c3的大小为8bytes。

 

         cout << "the size of PatClass4 object is: " << sizeof(c4) << endl;

         // PatClass4的对齐数为8bytes,它有一个成员变量char c1和一个成员变量double c2,合起来为9 bytes,由于

// 其对齐数为8bytes,因此需要填充7bytes,才能变成8的倍数。故此其对象c4的大小为16 bytes。

 

         cout << "the size of PatClass5 object is: " << sizeof(c5) << endl;

// PatClass5的对齐数为4 bytes,它只有一个成员变量int c1,合起来为4bytes,刚好是其对齐数的倍数。

// 故此其对象c5的大小为4 bytes。

 

         cout << "the size of PatClass6 object is: " << sizeof(c6) << endl;

// PatClass6的对齐数为4 bytes,它有一个成员变量char c2,并从PatClass5中继承来了int c1,合起来为5bytes,

// 因此需要填充3bytes,才能变成4的倍数。故此其对象c6的大小为8 bytes。

 

         return 0;

}

输出结果为:

关于内存对齐问题(一) - 玄机逸士 - 玄机逸士博客

         如果用#pragma pack(4)(在上面的程序中被注释了)指定全局对齐数为4bytes,结果如下:

         关于内存对齐问题(一) - 玄机逸士 - 玄机逸士博客

         其实这样的指定,只影响到了PatClass4,因为只有它有一个double成员变量,而sizeof(double)=8bytes,其他各类

均没有数据类型超过4bytes的。在前面曾经提及,一个类对象的内存对齐数 = min(指定的全局对齐数,成员变量数据

类型字节数最大者),因此在这个例子中PatClass4类型的对象的对齐数应该为4bytes。在PatClass类型的对象c4中,

成员变量double c2占8bytes,另外一个成员变量char c1占1byte,合起来一共9 bytes,因此要最小填充3 bytes,

     才能成员对齐数4的倍数,即此时PatClass4类型的对象的大小为12bytes。
C语言内存对齐实例详解 本文详细讲述了C语言程序设计中内存对其的概念与用法。分享给大家供大家参考之用。具体如下: 一、字节对齐基本概念 现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特定的内存地址访问,这就需要各种类型数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放,这就是对齐。 对齐的作用和原因:各个硬件平台对存储空间的处理上有很大的不同。一些平台对某些特定类型的数据只能从某些特定地址开始存取。比如有些架构的CPU在访问一个没有进行对齐的变量的时候会发生错误,那么在这种架构下编程必须保证字节对齐.其他平台可能 立即下载

相关推荐

GD32F103入门实践(一)配置环境,搭建工程模板,烧写程序

写在前面 本系列博客是我初学GD32F103的操作实录,我个人是个小白,在学习过程中真的也遇到了不少坑,因此我希望能记录下来,帮助到同样踩坑的你。 我的芯片是GD32F103ZE,软件是Keil,烧写用的是JLink。 材料准备 首先我在兆易创新官网(兆易创新),下载相关的文件。点击资料下载,在搜索框里输入“GD32F10”可以得到相关的资料,其他芯片类似。比较重要的是GD32F10x AddOn和GD32F10x Firmware Library(固件库),这两个必须下载。 下载Keil MDK5,这

qq_41208487的博客 3万+

socket编程中字节序、对齐和数据类型问题

1、字节序问题 2、对齐问题 系统默认是对齐的。 //32位机上占的是4+4+4=12个字节 struct stu{ int age; float higth; char sex; }; //32位机上占的是4+4+4+4=16个字节 struct stu{ int age; char name; float higth; char sex; }; //32位机上占的是4+4+4=12个字节 struct stu{ int ag

modi000的博客 857

下载Python3.10的相关方法及问题解决

下载Python3.10的相关方法及问题解决 报错unable to locate package python3.10-dev以及subprocess.CalledProcessError: Command ‘(‘lsb_release‘, ‘-a‘)‘ returned non-zero exit status 1问题解决

Istil 1555

sk_buff结构和函数分析

在wlan驱动中,数据读取写入是通过sk_buff这个结构体,而sk_buff结构主要作用是包含接收的缓冲数据,和它的包头信息。 如下是sk_buff的主要结构成员: struct sk_buff {... unsigned char *head; unsigned char *data; unsigned char *tail; unsigned char *end;...}; 当

胡LiuJia@BLOG 1201

yolov8涨点系列之轻量化主干网络替换

yolov8涨点系列之轻量化主干网络替换,以EfficientVit为例

zhang1379的博客 2887

Android SELinux——neverallow问题处理(十六)

遇到 neverallow 规则问题,千万别急着去注释/剔除里面原有的规则(原生的尽量别动)。增加 allow 规则是常见的解决办法,但是随着 android 版本的升级,系统对 SELinux 的管控越来越严,增加了大量的 neverallow。一般情况下,向默认标签授予权限的做法是错误的,其中许多权限都是 neverallow 规则所不允许的。按照上面方法去添加 SELinux 可能会违反了 neverallow 规则,编译时候会报 neverallow 相关的错误。

小旭的专栏 2671

C++内存中字节对齐问题分析与总结

一、什么是字节对齐        计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特 定的内存地址访问,这就需要各种类型数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放,这就是对齐。 二、对齐的作用和原因:     1、平台原因(移植原因):不是所有的硬件平台都能访问任意地址

cxstudying的专栏 522

RK3568平台(camera篇)点亮imx586摄像头

mipi摄像头硬件确认点:1.供电:5V,2.8V,1.2V,1.8V,reset脚(硬拉3.3,上电的时候从低到高),pwron脚外接3.3V。2,时钟:MCLKOUT是24兆时钟。3.4组差分mipi线。mipi的data线的波形为方波。

weixin_49303682的博客 7258

C语言字节对齐问题详解

    引言      考虑下面的结构体定义: 1 typedef struct{ 2 char c1; 3 short s; 4 char c2; 5 int i; 6 }T_FOO;      假设这个结构体的成员在内存中是紧凑排列的,且c1的起始地址是0,则s的地址就是1,c2的地址是3,i的地址是4。      现在,...

weixin_34367845的博客 1444

华为MetaERP在财务模块(GL/AP/AR/FA)及子账模块效率优化、月末关账加速、与外部系统对账方面,已形成一套**“并行+实时+智能化”**的完整技术方案

华为MetaERP推出"并行+实时+智能化"技术方案,显著提升财务模块效率:1)采用三级并行策略和内存计算,使子账模块单任务处理时间从142分钟降至9分钟;2)通过并行关账架构将月末关账时间从68小时压缩至7.2小时;3)运用AI智能对账提升效率50%,并支持异步流程和区块链审计。典型场景测试显示月结耗时下降89%,CPU利用率提升116%。方案建议分阶段实施,注意依赖分析、任务粒度设计和性能监控,避免过度并行。该方案已有效解决大型集团财务处理效率低、关账慢、对账难等痛点。

金牌架构师 557

《驾驭你的AI同事:WorkBuddy深度精通》027:11.1 私有知识库接入

11.1 私有知识库接入 —— 《驾驭你的AI同事:WorkBuddy深度精通》系列图文教程,配图已统一为规范示意图。

LuckyHanMo的博客 140

结构体在内存中的对齐规则

一个结构体变量定义完之后,其在内存中的存储并不等于其所包含元素的宽度之和。 例一:                                       #include                                       using namespace std;

dafanshu2009的专栏 365

解决宿主机Ping不通虚拟机的问题

在使用虚拟机的过程中,我们常常会遇到宿主机和虚拟机之间无法相互通信的问题。具体来说,我们要查看虚拟机和宿主机的 IP 地址,然后尝试进行 Ping 测试。在某些情况下,我们可能发现 Ping 虚拟机不通,接下来我将分享如何解决这个问题。

howard2005的专栏 7万+

C++成员变量内存对齐问题,ndk下非对齐的内存访问导致BUS_ADRALN

同样的代码,在vs下运行正常,在android ndk下却崩溃: signal 7(SIGBUS),code 1 (BUS_ADRALN),fault addr 0xe6b82793 Func(short *pVY[]) { short *dstY[2] = {pVY[0],pVY[1]};//使用backtrace定位,crash在这一句 } pVY[0],pVY[1]是从...

weixin_30634661的博客 1661

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

内存对齐方式

在结构体定义的时候,如果要将结构体向文件中写入的话.需要保证结构体在内存中不能出现内存陷阱.这就涉及到内存对齐的问题了.VC++中默认的对齐方式为两个字节如下为定义为一个字节,这样内存中就不会有什么陷阱了:#pragma pack(1)typedef struct{    char RiffID[4];    DWORD dwFileDataSize;   char WaveID[4];   ch

soar的专栏 826

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

VS C++字节对齐与内存投射

VS C++字节对齐方式 VS C++默认四字节对齐,在新建数据结构的时候,如下新建两个数据结构: typedef struct STRUCT_STREAM_BYTE{ char byte1; char s_precision[4]; char ubyte1; char d_byte[2]; }stream_Byte; typedef struct STRUCT_DATA_BYTE{ char byte1; float s_precision; uns

J6wuli的博客 812

C++中类的内存对齐

为什么占用8个字节呢?因为这个就和第一个易错点有联系了,因为现在这个类内部并没有定义有成员数据,c++用一个内存单元来表示这个实例对象的存在,这一个内存字节,因为存在虚函数表(4个字节),所以经过内存对齐之后,这个类所占用的内存大小就是8了,而不是4了。没错,在这个情况下是以4个字节作为对齐的,但是真的就是都是以4个字节作为内存对齐的标准的吗?这下懵逼了吧,现在的内存对齐的标准又变成了8个字节了,其实并不然。没错,结果并不是0而是1,这个没有定义任何成员变量也没有定义任何的虚函数的类占用的是一个字节内容。

大隐隐于野 393

内存分配,任意字节对齐

有这么一道题目,要求按任意字节对齐分配内存,接口:    char * aligned_malloc(int size, int alignment)//size 为分配的内存大小,alignment对齐基数(可以为任意数) 这个在gcc库函数里能找到源码,在ffdshow等开源代码里面也能找到源码,实现如下: void * aligned_malloc (int size, int ali

szu030606的专栏 2455

C语言结构体中内存对齐的问题

最近做手动socket发送和接收dns报文处理。 在处理返回的报文的时候,遇到一个结构体内存对齐的问题,导致报文解析不对。dns响应报文格式如下,具体详细自己百度了解。 为了直接处理响应报文,我定义了如下结构体。“` typedef unsigned int U32; typedef unsigned short U16; typedef unsigned char U8;typede

zengyaowu1988的博客 522

内存对齐的问题

#include /* test the pointer to pointer */ int main() { char c; char *p1; char **p2; p1 = &c; p2 = &p1; printf("%p\n", &c); //printf("%p\n", p1); printf("%p\n",

Allen.W的博客 358

Android平台,C/C++代码内存对齐问题(signal SIGBUS Error)

最近手机版本老出现崩溃,之前出现过,但很偶然。最近出现机率比较高,就跟查一下。 报了signal SIGBUS BUS Error,最终定位在uint32_t i32 = *((uint32_t*)m_data); 这句语出了问题, 确认m_data内存是正确的,并且在PC机上运行是正常的。 后面查到原因是x86架构CPU是支持内存非对齐访问,而手机的CPU采用的是RISC架构,为了提高访

zsJum的专栏 8617

关于字节对齐的一些问题

关于字节对齐的一些问题前言正题CPU从内存上读取数据的一些细节动手实践一下下面看一下结构体嵌套的情况 前言 写在前面,博主也是个菜鸟,只是在这里分享一些自己遇到的问题,如有表述不当的地方请谅解。 正题 关于字节对齐的问题其实很好理解,只要了解下CPU读取数据的细节再动手实践一下就一目了然了,下面是我了解到的CPU读取数据时的一些细节和实践的过程。 CPU从内存上读取数据的一些细节 首先看一下内存的排列: ![!](https://img-blog.csdnimg.cn/20201208124528

qq_45279672的博客 306

内存对齐、内存对齐规则解释、内存对齐原理

一、内存对齐的原因 我们都知道计算机是以字节(Byte)为单位划分的,理论上来说CPU是可以访问任一编号的字节数据的,我们又知道CPU的寻址其实是通过地址总线来访问内存的,CPU又分为32位和64位,在32位的CPU一次可以处理4个字节(Byte)的数据,那么CPU实际寻址的步长就是4个字节,也就是只对编号是4的倍数的内存地址进行寻址。同理64位的CPU的寻址步长是8字节,只对编号是8的倍数的内存...

草帽~小子^的博客 7393
上一篇: 理解左值与右值
下一篇: 关于内存对齐问题(二)
小文兄弟
博客等级 码龄17年 28粉丝 18原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值