字节对齐原则

  • 格式:pdf
  • 大小:403.45 KB
  • 文档页数:4

字节对齐原则

这个问题也是困扰了我很久的⼀个问题:

为了加快数据存取的速度,编译器默认情况下会对结构体成员和结构体本⾝存储位置进⾏处理,使其存放的起始地址是⼀定字节数的倍数,⽽不

是顺序存放,称为字节对齐.

设对齐字节数为n(n = 1,2,4,8,16),每个成员内存长度为Li,Max(Li)为最⼤的成员内存长度,字节对齐规则是:

1. 结构体对象的起始地址能够被Max(Li)所整除;

2. 结构体中每个成员相对于起始地址的偏移量,即对齐值应是min(n,Li)的倍数.若不满⾜对齐值的要求,编译器会在成员之间填充若⼲个字

节;

3. 结构体的总长度值应是min(n,Max)(Li)的倍数,若不满⾜总长度值的要求,编译器在为最后⼀个成员分配空间后,会在其后填充若⼲个字节.

(VC默认的对齐字节数n=8)

开不懂,请看下⾯例⼦:

#include

using namespace std;

// 1加1+编译器补充的2个再加上int 的4个(编译器⾃动加的)

typedef struct node1 // 1+1+(2)+4 = 8

{

char c1;

char c2;

int a;

}str1 ;

typedef struct str2 // 1+(3)+4+1+(3) = 12

{

char c1;

int a;

char c2;

}str2 ;

typedef struct str3 // 5+(3)+4+2+(2) = 16

{

char c1[5];

int b;

short c;

}str3 ;

typedef struct str4 // 5+(1)+(2)+4 = 12

{

char c1[5];

short c;

int b;

}str4 ;

typedef struct str5 // 1+1+(6)+8 = 16

{

char c1;

char c2;

double a;

}str5 ;

typedef struct str6 // 1+(7)+8+1+(7) = 24

{

char c1;

double a;

char c2;

}str6 ;

typedef struct str7

{

char c1;

str1 s; // 相当于吧str1的结构放在这 char,char,int

double b;

}str7 ; // 1+1+1+(1)+4+4 = 12

int main()

{

str1 s1;

str2 s2;

str3 s3;

str4 s4;

str5 s5;

str5 s6;

str7 s7;

str8 s8;

cout << "s1 = " << sizeof(s1)<

合集下载

C语言的字节对齐及#pragmapack的使用

C语言的字节对齐及#pragmapack的使用

C语言的字节对齐及#pragmapack的使用

C编译器的缺省字节对齐方式(自然对界)

在缺省情况下,C编译器为每一个变量或是数据单元按其自然对界条件分配空间。

在结构中,编译器为结构的每个成员按其自然对界(alignment)条件分配空间。各个成员按照它们被声明的顺序在内存中顺序存储(成员之间可能有插入的空字节),第一个成员的地址和整个结构的地址相同。

C编译器缺省的结构成员自然对界条件为“N字节对齐”,N即该成员数据类型的长度。如int型成员的自然对界条件为4字节对齐,而double类型的结构成员的自然对界条件为8字节对齐。若该成员的起始偏移不位于该成员的“默认自然对界条件”上,则在前一个节面后面添加适当个数的空字节。

C编译器缺省的结构整体的自然对界条件为:该结构所有成员中要求的最大自然对界条件。若结构体各成员长度之和不为“结构整体自然对界条件的整数倍,则在最后一个成员后填充空字节。

例子1(分析结构各成员的默认字节对界条界条件和结构整体的默认字节对界条件):

struct Test

{

char x1; // 成员x1为char型(其起始地址必须1字节对界),其偏移地址为0

char x2; // 成员x2为char型(其起始地址必须1字节对界,其偏移地址为1

float x3; // 成员x3为float型(其起始地址必须4字节对界),编译器在x2和x3之间填充了两个空字节,其偏移地址为4

char x4; // 成员x4为char型(其起始地址必须1字节对界),其偏移地址为8

};

因为Test结构体中,最大的成员为flaot x3,因些此结构体的自然对界条件为4字节对齐。则结构体长度就为12字节,内存布局为1100 1111 1000。

例子2:

#include

//#pragma pack(2)

typedef struct

{

int aa1; //4个字节对齐 1111

c语言结构体16字节对齐

c语言结构体16字节对齐

第 1 页 共 2 页 c语言结构体16字节对齐

【最新版】

目录

1.结构体的概念

2.16 字节对齐的重要性

3.C 语言中的结构体对齐规则

4.16 字节对齐的实现方法

5.应用实例

正文

一、结构体的概念

结构体是一种复合数据类型,它可以将不同类型的数据组合在一起。结构体主要应用于以下场景:当需要将一组相关联的数据组织在一起时,可以使用结构体来描述这些数据。结构体可以包含各种不同类型的成员,如整型、浮点型、字符型等。

二、16 字节对齐的重要性

在计算机系统中,数据存储和访问通常是以字节为单位的。不同的数据类型所占用的字节数是不同的。结构体中的成员也需要占用一定的字节空间。为了提高数据访问的效率,需要对结构体中的成员进行对齐。对齐的目的是使结构体成员的首地址能够被其大小所整除,这样可以减少访问数据时的内存浪费。

三、C 语言中的结构体对齐规则

C 语言中的结构体对齐规则是按照成员的大小进行排列,从大到小。当一个成员的大小小于等于 16 字节时,它会被紧挨着放置在前一个成员的后面。当一个成员的大小大于 16 字节时,它会被从下一个 16 字节的位置开始放置。 第 2 页 共 2 页 四、16 字节对齐的实现方法

要实现 16 字节对齐,需要在结构体定义时注意成员的排列顺序和数据类型。首先,将较大的成员放在结构体的前面,较小的成员放在后面。其次,可以使用预编译指令#pragma pack 来指定对齐的字节数。例如,可以使用#pragma pack(2) 来指定 16 字节对齐。

五、应用实例

以下是一个使用 16 字节对齐的结构体应用实例:

```c

#pragma pack(2)

typedef struct {

int a; // 4 字节

float b; // 4 字节

char c; // 1 字节

char d; // 1 字节

C语言字节对齐

C语言字节对齐

C语言字节对齐

字节对齐的由来

程序在运行时会将数据临时存放在内存中,芯片内核需要对这些数据进行计算,不断的

读取内存以获得数据,并将计算结果写入内存。计算机体系经过若干年的发展,最终确定了

以8bits作为其基本的存储单元——byte(字节),这是每个地址所对应的最小访问单元,

在C语言中对应一个char型的变量。

下图为芯片内核访问内存的示意图。芯片内核通过控制总线控制内存的动作,通过地址

总线告知内存地址,数据总线上出现交互的数据。

图1访问内存示意图

假设上图是8位机的示意图,那么数据总线的宽度是8bits,由8根数据线组成,这样

芯片内核与内存之间一次就可以同时交换8个bits的数据,正好是一个字节。图中右侧的

每个小格子代表一个存储地址,对应一个字节。

下面通过一段C语言代码来具体看看芯片内核与内存之间的数据交互过程。

chardata[2];data[0]=2;data[1]=data[0]+1;

第一行代码定义了2个字节的数组data。假设data数组被编译到地址0x100,那么

data[0]这个字节就被存储在地址为0x100的内存空间,data[1]这个字节就被存储在地址为

0x101的内存空间。

第二行对应的硬件动作是将数据2存入到data[0]中,也就是将数据2存入到内存中的

0x100地址,执行这条语句时,芯片内核对控制总线、地址总线和数据总线进行操作,控制

总线上出现写信号,地址总线上出现数据0x100,数据总线上出现数据0x02。此时内存就

知道需要将数据2写入到地址0x100中,完成一次写操作。

第三行先读出data[0]中的数据,芯片内核将控制总线置为读信号,将地址总线置为

0x100,此时,内存就会从其内部取出0x100地址中的数据,也就是数据2,2将出现在数

据总线上,此时芯片内核就会通过数据总线读取到data[0]中的数据了。接下来芯片内核计

算2+1=3,需要将数字3写入到data[1]中,芯片内核将控制总线置为写信号,将地址总线

字节对齐和边界对齐介绍

字节对齐和边界对齐介绍

字节对齐和边界对齐介绍

⼀.什么是字节对齐,为什么要对齐? 现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定

类型变量的时候经常在特 定的内存地址访问,这就需要各种类型数据按照⼀定的规则在空间上排列,⽽不是顺序的⼀个接⼀个的排放,这

就是对齐。 对齐的作⽤和原因:各个硬件平台对存储空间的处理上有很⼤的不同。⼀些平台对某些特定类型的数据只能从某些特定地址开始存取。

⽐如有些架构的CPU在访问 ⼀个没有进⾏对齐的变量的时候会发⽣错误,那么在这种架构下编程必须保证字节对齐.其他平台可能没有这种

情况,但是最常见的是如果不按照适合其平台要求对 数据存放进⾏对齐,会在存取效率上带来损失。⽐如有些平台每次读都是从偶地址开

始,如果⼀个int型(假设为32位系统)如果存放在偶地址开始的地⽅,那 么⼀个读周期就可以读出这32bit,⽽如果存放在奇地址开始的

地⽅,就需要2个读周期,并对两次读出的结果的⾼低字节进⾏拼凑才能得到该32bit数 据。显然在读取效率上下降很多。

⼆.字节对齐对程序的影响: 先让我们看⼏个例⼦吧(32bit,x86环境,gcc编译器):

设结构体如下定义:struct A

{

int a;

char b;

short c;

};

struct B

{

char b;

int a;

short c;

};

现在已知32位机器上各种数据类型的长度如下:char:1(有符号⽆符号同)

short:2(有符号⽆符号同)

int:4(有符号⽆符号同)

long:4(有符号⽆符号同)

float:4 double:8

那么上⾯两个结构⼤⼩如何呢?

结果是:sizeof(strcut A)值为8

sizeof(struct B)的值却是12

结构体A中包含了4字节长度的int⼀个,1字节长度的char⼀个和2字节长度的short型数据⼀个,B也⼀样;按理说A,B⼤⼩应该都是7字节。