首页 > 其他分享 >字节对齐

字节对齐

时间:2023-03-25 20:12:39浏览次数:43  
标签:-------- 字节 int 数据类型 对齐 结构

引用: https://www.cnblogs.com/sky-heaven/p/4137770.html

在用sizeof运算符求算某结构体所占空间时,并不是简单地将结构体中所有元素各自占的空间相加,这里涉及到内存字节对齐的问题。从理论上讲,对于任何 变量的访问都可以从任何地址开始访问,但是事实上不是如此,实际上访问特定类型的变量只能在特定的地址访问,这就需要各个变量在空间上按一定的规则排列, 而不是简单地顺序排列,这就是内存对齐。

内存对齐的原因:

1)某些平台只能在特定的地址处访问特定类型的数据;

2)提高存取数据的速度。比如有的平台每次都是从偶地址处读取数据,对于一个int型的变量,若从偶地址单元处存放,则只需一个读取周期即可读取该变量;但是若从奇地址单元处存放,则需要2个读取周期读取该变量。

win32平台下的微软C编译器对齐策略:

1)结构体变量的首地址能够被其最宽数据类型成员的大小整除。编译器在为结构体变量开辟空间时,首先找到结构体中最宽的数据类型,然后寻找内存地址能被该数据类型大小整除的位置,这个位置作为结构体变量的首地址。而将最宽数据类型的大小作为对齐标准。

2)结构体每个成员相对结构体首地址的偏移量(offset)都是每个成员本身大小的整数倍,如有需要会在成员之间填充字节。编译器在为结构体成员开辟空 间时,首先检查预开辟空间的地址相对于结构体首地址的偏移量是否为该成员大小的整数倍,若是,则存放该成员;若不是,则填充若干字节,以达到整数倍的要 求。

3)结构体变量所占空间的大小必定是最宽数据类型大小的整数倍。如有需要会在最后一个成员末尾填充若干字节使得所占空间大小是最宽数据类型大小的整数倍。

 

下面看一下sizeof在计算结构体大小的时候具体是怎样计算的

1.test1 空结构体

typedef struct node
{
 
}S;

则sizeof(S)=1;或sizeof(S)=0;

在C++中占1字节,而在C中占0字节。

2.test2

?
typedef struct node1
{
int a;
char b;
short c;
}S1;

则sizeof(S1)=8。这是因为结构体node1中最长的数据类型是int,占4个字节,因此以4字节对齐,则该结构体在内存中存放方式为

|--------int--------| 4字节

|char|----|--short-| 4字节

总共占8字节

3.test3

 
typedef struct node2
{
char a;
int b;
short c;
}S2;

则siezof(S3)=12.最长数据类型为int,占4个字节。因此以4字节对齐,其在内存空间存放方式如下:

|char|----|----|----| 4字节

|--------int--------| 4字节

|--short--|----|----| 4字节

总共占12个字节

4.test4 含有静态数据成员

 
typedef struct node3
{
int a;
short b;
static int c;
}S3;

 

则sizeof(S3)=8.这里结构体中包含静态数据成员,而静态数据成员的存放位置与结构体实例的存储地址无关(注意只有在C++中结构体中才能含有静态数据成员,而C中结构体中是不允许含有静态数据成员的)。其在内存中存储方式如下:

|--------int--------| 4字节

|--short-|----|----| 4字节

而变量c是单独存放在静态数据区的,因此用siezof计算其大小时没有将c所占的空间计算进来。

5.test5 结构体中含有结构体

 
typedef struct node4
{
bool a;
S1 s1;
short b;
}S4;

则sizeof(S4)=16。是因为s1占8字节,而s1中最长数据类型为int,占4个字节,bool类型1个字节,short占2字节,因此以4字节对齐,则存储方式为

|-------bool--------| 4字节

|-------s1----------| 8字节

|-------short-------| 4字节

6.test6

typedef struct node5
{
bool a;
S1 s1;
double b;
int c;
}S5;

则sizeof(S5)=32。是因为s1占8字节,而s1中最长数据类型为int,占4字节,而double占8字节,因此以8字节对齐,则存放方式为:

|--------bool--------| 8字节

|---------s1---------| 8字节

|--------double------| 8字节

|----int----|---------| 8字节

7.test7

若在程序中使用了#pragma pack(n)命令强制以n字节对齐时,默认情况下n为8.

则比较n和结构体中最长数据类型所占的字节大小,取两者中小的一个作为对齐标准。

若需取消强制对齐方式,则可用命令#pragma pack()

如果在程序开头使用命令#pragma pack(4),对于下面的结构体

typedef struct node5
{
bool a;
S1 s1;
double b;
int c;
}S5;

则sizeof(S5)=24.因为强制以4字节对齐,而S5中最长数据类型为double,占8字节,因此以4字节对齐。在内存中存放方式为:

|-----------a--------| 4字节

|--------s1----------| 4字节

|--------s1----------| 4字节

|--------b-----------| 4字节

|--------b-----------| 4字节

|---------c----------| 4字节

总结一下,在计算sizeof时主要注意一下几点:

1)若为空结构体,则只占1个字节的单元

2)若结构体中所有数据类型都相同,则其所占空间为 成员数据类型长度×成员个数

若结构体中数据类型不同,则取最长数据类型成员所占的空间为对齐标准,数据成员包含另一个结构体变量t的话,则取t中最 长数据类型与其他数据成员比较,取最长的作为对齐标准,但是t存放时看做一个单位存放,只需看其他成员即可。

3)若使用了#pragma pack(n)命令强制对齐标准,则取n和结构体中最长数据类型占的字节数两者之中的小者作为对齐标准。

 

另外除了结构体中存在对齐之外,普通的变量存储也存在字节对齐的情况,即自身对齐。编译器规定:普通变量的存储首地址必须能被该变量的数据类型宽度整除。

标签:--------,字节,int,数据类型,对齐,结构
From: https://www.cnblogs.com/lianglianglu/p/17255468.html

相关文章

  • 内存对齐
    #include<iostream>/*#pragmapack(4)*/usingstd::cout;usingstd::endl;//1421structx{chara;intb;shortc;chard;}MyStructX;......
  • css-输入框和按钮水平对齐
    <style> .container{ margin:0auto; margin-top:160px; width:600px; } .search{ width:100%; margin-top:20px; height:40px; } .searchin......
  • CSS:text-align-last文本最后一行的对齐方式
    在开发过程中多行文本时出现了其他行左对齐,最后一行右对齐的情况text-align:规定行内内容如何相对它的块父元素对齐。而且它并不控制块元素自己的对齐,只控制它的行内内容的......
  • css基础 CSS 布局 – Overflow、Float 浮动、CSS 布局 – 水平 垂直居中对齐
    阅读目录CSS布局–Overflowoverflow:visibleoverflow:hiddenoverflow:scrolloverflow:autoverflow-x和overflow-y所有CSSOverflow属性CSSFloat浮动float属性......
  • 字节类型解析
    python中使用字节类型(bytes)来表示二进制信息,它是由单个字节构成的不可变序列。字节类型的字面量的语法与字符串大致相同,只是添加了一个前缀b。字节类型的字面量中只允......
  • 跟着字节AB工具DataTester,5步开启一个实验
    更多技术交流、求职机会,欢迎关注字节跳动数据平台微信公众号,回复【1】进入官方交流群 火山引擎A/B测试平台DataTester孵化于字节跳动业务内部,在字节跳动,“万事皆A/B,一切可......
  • 跟着字节AB工具DataTester,5步开启一个实验
    更多技术交流、求职机会,欢迎关注字节跳动数据平台微信公众号,回复【1】进入官方交流群 火山引擎A/B测试平台DataTester孵化于字节跳动业务内部,在字节跳动,“万事皆A/B,......
  • 类字节码
      第一次自己看类字节码,还挺有意思 魔数:没看到在哪常量池:确实包含很多数据,包括变量属性、类型名、方法名等等访问标志:没看到类索引、父类索引、接口索引:只看到了......
  • css实现文本水平&垂直对齐的三种方式
    第一种:使用padding和text-align:center例如:.center{padding:100px0;border:1pxsolidgreen;text-align:center;} 第二种:使用line-heig......
  • 字节面试官心声:个个都说会自动化,结果面试一问细节全露馅了
     今年部门要招三个自动化测试,年前我面试了几十位候选人。发现一个很奇怪的现象,面试中一问到元素定位、框架api、脚本编写之类的,很多候选人都对答如流。但是一问到实际项......