C++中的字节对齐机制

存内计算路线再获加持,清华存内芯片登Science 通过这种方法,可以比较有效的控制二氧化铪忆阻层中的微观变化,以及内部的温度和电场,使得器件具有非常优异的电学特性,而且可以在工厂里大规模生产,推动了高性能忆阻器阵列的诞生。团队搭建了全硬件构成的完整存算一体系统,如下图7所示,在系统里集成了多个忆阻器阵列,并在该系统上高效运行了卷积神经网络算法,成功验证了图像识别功能,证明了存算一体架构全硬件实现的可行性,并且成功实现了以更小的功耗和更低的硬件成本完成复杂的计算[6]。根据测试,在一般神经网络中权重更新的最后阶段,调整步长非常接近0,如图9(C)所示, 阅读详情
1. 基本概念
字节对齐:计算机存储系统中以Byte为单位存储数据,不同数据类型所占的空间不同,
如:整型(int)数据占4个字节,字符型(char)数据占一个字节,短整型(short)数据占两个字节,等等。
计算机为了快速的读写数据,默认情况下将数据存放在某个地址的起始位置,如:整型数据(int)默认存储
在地址能被4整除的起始位置,字符型数据(char)可以存放在任何地址位置(被1整除),短整型(short)
数据存储在地址能被2整除的起始位置。这就是默认字节对齐方式。


2. 举例说明
很显然默认对齐方式会浪费很多空间,例如如下结构:
struct student
{
    char name[5];
    int num;
    short score;
}
本来只用了11bytes(5+4+2)的空间,但是由于int型默认4字节对齐,存放在地址能被4整除的起始位置,
即:如果name[5]从0开始存放,它占5bytes,而num则从第8(偏移量)个字节开始存放。所以sizeof(student)=16。
于是中间空出几个字节闲置着。但这样便于计算机快速读写数据,是一种以空间换取时间的方式。其数据对齐如下图:


|char|char|char|char|
|char|----|----|----|
|--------int--------|
|--short--|----|----|


如果我们将结构体中变量的顺序改变为:
struct student
{
    int num;
    char name[5];
    short score;
}
则,num从0开始存放,而name从第4(偏移量)个字节开始存放,连续5个字节,score从第10(偏移量)开始存放,
故sizeof(student)=12。其数据对齐如下图:


|--------int--------|
|char|char|char|char|
|char|----|--short--|




如果我们将结构体中变量的顺序再次改为为:
struct student
{
    int num;
    short score;
    char name[5];
}
则,sizeof(student)=12。其数据对齐如下图:


|--------int--------|
|--short--|char|char|
|char|char|char|----|




验证代码如下:


#include <stdio.h>


typedef struct
{
    char name[5];
    int num;
    short score;
}student1;


typedef struct
{
    int num;
    char name[5];
    short score;
}student2;


typedef struct
{
    int num;
    short score;
    char name[5];
}student3;


int main()
{
    student1 s1={"Tom",1001,90};
    student2 s2={1002,"Mike",91};
    student3 s3={1003,92,"Jack"};


    printf("student1 size = %d\n",sizeof(s1));
    printf("student2 size = %d\n",sizeof(s2));
    printf("student3 size = %d\n",sizeof(s3));


    printf("\nstudent1 address : 0xx\n",&s1);
    printf("   name  address : 0xx\n",s1.name);
    printf("   num   address : 0xx\n",&s1.num);
    printf("   score address : 0xx\n",&s1.score);


    printf("\nstudent2 address : 0xx\n",&s2);
    printf("   num   address : 0xx\n",&s2.num);
    printf("   name  address : 0xx\n",s2.name);
    printf("   score address : 0xx\n",&s2.score);


    printf("\nstudent3 address : 0xx\n",&s3);
    printf("   num   address : 0xx\n",&s3.num);
    printf("   score address : 0xx\n",&s3.score);
    printf("   name  address : 0xx\n",s3.name);


    return 0;
}
运行结果如下:
student1 size = 16
student2 size = 12
student3 size = 12


student1 address : 0x0012ff70
   name  address : 0x0012ff70
   num   address : 0x0012ff78
   score address : 0x0012ff7c


student2 address : 0x0012ff64
   num   address : 0x0012ff64
   name  address : 0x0012ff68
   score address : 0x0012ff6e


student3 address : 0x0012ff58
   num   address : 0x0012ff58
   score address : 0x0012ff5c
   name  address : 0x0012ff5e




3. #pragma pack()命令
为了节省空间,我们可以在编码时通过#pragma pack()命令指定程序的对齐方式,括号中是对齐的字节数,
若该命令括号中的内容为空,则为默认对齐方式。例如,对于上面第一个结构体,如果通过该命令手动设置对齐字节数如下:


#pragma pack(2) //设置2字节对齐
struct strdent
{
    char name[5]; //本身1字节对齐,比2字节对齐小,按1字节对齐
    int num;          //本身4字节对齐,比2字节对齐大,按2字节对齐
    short score;    //本身也2字节对齐,仍然按2字节对齐
}
#pragma pack() //取消设置的字节对齐方式


则,num从第6(偏移量)个字节开始存放,score从第10(偏移量)个字节开始存放,故sizeof(student)=12,其数据对齐如下图:
|char|char|
|char|char|
|char|-----|
|----int----|
|----int----|
|--short---|


这样改变默认的字节对齐方式可以更充分地利用存储空间,但是这会降低计算机读写数据的速度,是一种以时间换取空间的方式。


验证代码如下:


#include <stdio.h>


#pragma pack(2)
typedef struct
{
    char name[5];
    int num;
    short score;
}student1;


typedef struct
{
    int num;
    char name[5];
    short score;
}student2;


typedef struct
{
    int num;
    short score;
    char name[5];
}student3;
#pragma pack()


int main()
{
    student1 s1={"Tom",1001,90};
    student2 s2={1002,"Mike",91};
    student3 s3={1003,92,"Jack"};


    printf("student1 size = %d\n",sizeof(s1));
    printf("student2 size = %d\n",sizeof(s2));
    printf("student3 size = %d\n",sizeof(s3));


    printf("\nstudent1 address : 0xx\n",&s1);
    printf("   name  address : 0xx\n",s1.name);
    printf("   num   address : 0xx\n",&s1.num);
    printf("   score address : 0xx\n",&s1.score);


    printf("\nstudent2 address : 0xx\n",&s2);
    printf("   num   address : 0xx\n",&s2.num);
    printf("   name  address : 0xx\n",s2.name);
    printf("   score address : 0xx\n",&s2.score);


    printf("\nstudent3 address : 0xx\n",&s3);
    printf("   num   address : 0xx\n",&s3.num);
    printf("   score address : 0xx\n",&s3.score);
    printf("   name  address : 0xx\n",s3.name);


    return 0;
}


运行结果如下:


student1 size = 12
student2 size = 12
student3 size = 12


student1 address : 0x0013ff74
   name  address : 0x0013ff74
   num   address : 0x0013ff7a
   score address : 0x0013ff7e


student2 address : 0x0013ff68
   num   address : 0x0013ff68
   name  address : 0x0013ff6c
   score address : 0x0013ff72


student3 address : 0x0013ff5c
   num   address : 0x0013ff5c
   score address : 0x0013ff60
   name  address : 0x0013ff62


若该为#pragma pack(1),则运行结果如下:


student1 size = 11
student2 size = 11
student3 size = 11


student1 address : 0x0013ff74
   name  address : 0x0013ff74
   num   address : 0x0013ff79
   score address : 0x0013ff7d


student2 address : 0x0013ff68
   num   address : 0x0013ff68
   name  address : 0x0013ff6c
   score address : 0x0013ff71


student3 address : 0x0013ff5c
   num   address : 0x0013ff5c
   score address : 0x0013ff60
   name  address : 0x0013ff62




4. 例子
程序如下:
#include <stdio.h>


class A1
{
public:
    int a;
    static int b;


    A1();
    ~A1();
};


class A2
{
public:
    int a;
    char c;


    A2();
    ~A2();
};


class A3
{
public:
    float a;
    char c;


    A3();
    ~A3();
};


class A4
{
public:
    float a;
    int b;
    char c;
    
    A4();
    ~A4();
};


class A5
{
public:
    double d;
    float a;
    int b;
    char c;
    
    A5();
    ~A5();
};


main()
{
    printf("A1 size = %d\n",sizeof(A1));
    printf("A2 size = %d\n",sizeof(A2));
    printf("A3 size = %d\n",sizeof(A3));
    printf("A4 size = %d\n",sizeof(A4));
    printf("A5 size = %d\n",sizeof(A5));
}
该例子采取默认对齐方式,运行结果如下:




A1 size = 4
A2 size = 8
A3 size = 8
A4 size = 12
A5 size = 24
STM32的DMA模块及Protues仿真实验 (一)DMA简介      DMA(Direct Memory Access,直接存储器访问), 用于在外设与存储器之间以及存储器与存储器之间提供高速数据传输。可以在无需任何 CPU 操作的情况下通过 DMA 快速移动数据。这样节省的 CPU 资源可 供其它操作使用。      STM32F407共有两个 DMA 控制器,总共有 16 个数据流(每个控制器 8 个),每一个 DMA 控制器都用于管理 一个或多 阅读详情

相关推荐

iStore增强插件 如何重塑家庭网络与存储体验

本文深入解析了iStore增强插件如何重塑家庭数字生活体验。它通过集成智能流控、一键式文件共享、媒体服务器及智能家居网关等功能,将复杂的网络配置、存储管理与设备协同简化为图形化操作,有效解决了家庭网络卡顿、数据割裂与使用门槛高等核心痛点,让普通用户也能轻松打造高效、稳定、安全的家庭数字中枢。

prometheus9mon的博客 648

折叠方阵

给定一个起始数(大于等于1,小于等于20)和方阵的阶数(大于等于1,小于等于20),编程求得并输出该折叠方阵。一个起始数为10,4阶折叠方阵为:     10  11  14  19   13  12  15  20   18  17  16  21   25  24  23  22   【输入形式】   从标准输入中输入两个正整数分别表示起始数和方阵的阶数,以一个空格分隔这两个

WuqiushiApril的博客 3572

人大金仓的‘影子表’sys_user:搞懂Schema优先级,告别字段不存在的报错

本文深入解析人大金仓数据库中‘影子表’sys_user的Schema优先级问题,帮助开发者解决字段不存在的报错。通过分析Schema搜索路径机制,提供四种解决方案,包括连接时指定Schema、动态调整搜索路径、永久修改用户设置和使用完全限定表名,确保查询准确无误。

weixin_30329623的博客 596

C/C++左对齐,宽五格

左对齐,宽5格输出 %5d是格式控制字符串,表示输出占5个字符的十进制整数,右对齐,不够用空格补齐。 5是输出最小宽度,用于控制显示数值的宽度,是一个可选的指定最小值字段宽度的十进制数字字符串。如果转换值字符少于字段宽度,该字段将从左到右按指定的字段宽度填充。如果指定了左边调整选项,字段将在右边填充。如果转换结果宽于字段宽度,将扩展该字段以包含转换后的结果,不会发生截断。 5前面是-则表示左对齐,无符号则默认为+右对齐。 代码 printf("%-5d",result[i][j]); ...

qq_44627816的博客 5108

用C#和MQTTnet在WinForm里做个简易物联网监控后台(附完整源码)

本文详细介绍了如何使用C#和MQTTnet库在WinForm中构建一个简易物联网监控后台。通过实战案例,包括环境配置、MQTT服务端实现、客户端监控功能及高级优化技巧,帮助开发者快速搭建高效的物联网监控系统,适用于工业自动化和智能家居场景。

weixin_29540599的博客 393

(SCADA)监控与数据采集系统

SCADA应用于监控和采集数据来控制工业过程软件。它通过收集和传输实时数据,帮助操作员监视和控制各种设备和过程。

软件技术的专栏 4544

C/C++字节对齐规则

字节对齐与具体编译器相关,但一般都遵循以下三条规则: (1)结构体变量的首地址能够被其最宽基本类型成员的大小所整除; (2)结构体每个成员相对于结构体首地址的偏移量,都是#pragma pack指定的数值和该成员大小中较小那个的整数倍。如有需要编译器会在成员之间加上填充字节; (3)结构体的总大小为结构体最宽基本类型成员大小与#pragma pack指定的数值中,较小那个的整数倍,如有需要编译器会...

sj_djw的博客 1431

[QMT量化交易小白入门]-三十五、如何将聚宽策略信号转为QMT实盘交易

Flask是一个轻量级的Web应用框架,它提供了简单而灵活的方式来构建Web应用程序。在本案例中,将使用Flask来搭建一个本地服务,用于监听来自jq2qmt.py脚本的交易信号,并根据信号执行相应的下单操作。

木头大左的博客 2696

输出各种基本类型所占用的字节长度

#include using namespace std; int main( ) {int a; float b; double c; char d; cout cout cout cout return 0; }   int 型占的字节数4 float 型占的字节数4 double 型占的字节数8 char 型占的字节数1 Press any key to

w92a01n19g的专栏 901

北斗导航 | 卫星/惯导组合导航方法

从组合导航结构方面来讲,卫星/惯导(下文以GPS/INS)组合模式一般分为三种,即松组合、紧组合和超紧组合(即深组合)。

尘世冰封的专栏 1538

4.3 Langfuse 集成实战:追踪 OpenAI、LangChain 和 LangGraph 应用

本文介绍了如何将Langfuse集成到不同类型的AI应用中,包括原生OpenAI、LangChain和LangGraph应用。主要内容包括: 两种集成模式:手动追踪(精确控制)和自动追踪(通过回调机制) 三种应用场景的集成方案: 原生OpenAI应用:使用langfuse.trace()手动记录对话流程、LLM调用和工具执行 LangChain应用:通过LangfuseCallbackHandler自动追踪Agent执行过程 LangGraph应用:与LangChain相同的自动追踪方式,可可视化节点和状态

yonggeit的博客 3303

java岗位与c 岗位_请问java语言机制中有没有字节对齐?为什么样Java提供的就业岗位远远多于C/C++...

在上一篇文章中,小编为您详细介绍了关于《乌云为什么样是黑色的?我家电脑开程序关闭程序都比以前慢很多》相关知识。本篇中小编将再为您讲解标题请问java语言机制中有没有字节对齐?为什么样Java提供的就业岗位远远多于C/C++。字节对齐是为了什么?为了提高处理器对存储器的访问性能。字节对齐不是语言强制要求,是硬件上对memory存储信息时做的①些约束。所以C/C++有字节对齐,java语言也有。C/C...

weixin_30425639的博客 120

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

计算机操作系统的字节对齐

字节对齐是计算机系统中为了提高数据访问效率,在内存中对数据存储位置进行的一种约束机制。操作系统和编译器会根据硬件平台的要求,对数据进行“对齐”,即让数据的起始地址满足特定的对齐条件。

qq_45797625的博客 1139

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

OV9734 DATASHEET,完整规格书

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

字节对齐提高存取速度

编译过程中c++编译器为了提高存取速度,设置了在存储格式上的字节对齐。  一、概念         对齐跟数据在内存中的位置有关。如果一个变量的内存地址正好位于它长度的整数倍,他就被称做自然对齐。比如在32位cpu下,假设一个整型变量的地址为0x00000004,那它就是自然对齐的。    注意32位cpu一次读取32位(由于8位编址,也就是读取4个地址的数据,16位编址的话就只读

huangleijay的专栏 1519

蓝牙模块HM-10手册

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

c++内存中字节对齐问题详解

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

xietingcandice的专栏 699

C++结构体字节对齐(c++常见问题开篇)

本站文章均为Jensen抹茶喵原创,转载务必在明显处注明:转载自【博客园】原文链接:http://www.cnblogs.com/JensenCat/p/4770171.html 1.0版本: 这里是头文件结构的定义: 一个非字节对齐结构体_tagTest2 一个字节对齐_tagTest3 (使用#pragma pack(push,1)来使字节以1个来对齐 , 使用#p...

djhefwjl82876的博客 142

C/C++字节对齐问题

From: http://blog.youkuaiyun.com/alex_bn/article/details/6770788   首先来看下在C/C++中定义如下的结构体,然后对他们分别进行sizeof()运算,看看结果会如何 struct A {      int a;      char b;      short c; }; struct B {      char b

JoeBlackZQQ的专栏 1040

vs2005中字节对齐研究

一、什么是字节对齐,为什么要对齐? [本段Quote自]   现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定类型变量的时候经常在特定的内存地址访问,这就需要各种类型数据按照一定的规则在空间上排列,而不是顺序的一个接一个的排放,这就是对齐。   对齐的作用和原因:各个硬件平台对存储空间的处理上有很大的不同。一些

2033

C/C++中数据大小、字节对齐、内存占用总结

数据大小获取 sizeof()操作符,求占用空间,对数组而言大小为 type大小 * 数据个数; int a[] = {1,2,3,4,5} sizeof(a) = 20 sizeof(&a) = 4 特殊的:在string时,由于字符串本质上就是自带‘\0’结尾的 char[] 数组,而char 的大小有恰好为1, 因此sizeof()就正好会是数组的长度; 在C++98中是不允许对类的非静态成员变量使用sizeof()的,而在C++11中是合法的; 根据 C99 规定,size..

Mr_Xuf的博客 4051

网络VS C++字节对齐

我们知道的当一个结构体,如果我们想知道他占多少内存空间的话我们可以利用sizeof()来查看,但是有时候sizeof()得出的结构竟然和我们想象的不一样,这和编译器有很大的关系。编译器有自己的字节对齐机制,他为了某些原因,在内存上进行了一些调整。和填充,导致得到了与我们想法不一样的结果。虽然vc字节对齐网上有很多资料,但是呢,下面我就说说自己的理解,自己对这套规则的记忆方法。 采

1231

字节对齐和C/C++函数调用方式学习总结

前言:《***软件编程规范》中提到:“在定义结构数据类型时,为了提高系统效率,要注意4字节对齐原则……”。本文解释x86上字节对齐的机制,其他架构读者可自行试验。同时,本文对C/C++的函数调用方式进行了讨论。1.先看下面的例子:struct A{ char c1; int i; short s; int j;}a; struct B{ int i;

menuconfig的专栏 2449

字节对齐和C/C++函数调用方式学习总结(多篇节选)

字节对齐和C/C++函数调用方式学习总结created: 04-06-17last saved: author: ayixidelu前言:《***软件编程规范》中提到:“在定义结构数据类型时,为了提高系统效率,要注意4字节对齐原则……”。本文解释x86上字节对齐的机制,其他架构读者可自行试验。同时,本文对C/C++的函数调用方式进行了讨论。BTW想了几天要在休息时间写个总结但是直到今天18日才动手

mudboy的专栏 2909

C++ JNI 常用函数自查表

jstring chartoJstring(JNIEnv *env, char *pat, int length) { jclass strClass = env->FindClass("java/lang/String"); jmethodID ctorID = env->GetMethodID(strClass, "<init>", "([BLjava/lang/String;).

Android小码家 276
上一篇: 联合体和结构体字节对齐
下一篇: 联合体初始化的方法
fjweaponlwp
博客等级 码龄15年 4粉丝 5原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值