C语言结构体的字节对齐及指定对齐方式

合集下载

C语言结构体字节对齐简单计算方法

C语言结构体字节对齐简单计算方法

C语⾔结构体字节对齐简单计算⽅法
1.在C语⾔⾥⾯每⼀种数据类型都有字节对齐⽐如在32位操作系统下:整型的⾃⾝对齐数就是 4 字节,字符型就是 1 字节,double就是 8 字节。

但是结构体的计算⽅式就和普通的数据类型不⼀样。

在C语⾔⾥⾯字节对齐的⽅式主要根据“有效对齐数”来确定,那么有效对齐数是怎杨确定的呢?
在结构体⾥⾯::: 有效字节对齐数 = (⾃⾝对齐数 < 最⼤字节)?(⾃⾝对齐数):(最⼤字节);
⾃⾝对齐数 = 4字节(32位操作系统);(8 字节为32位操作系统)。

最⼤字节数 = 结构体⾥⾯最⼤的⼀个数据类型所占的字节数。

列:struct test{
char a;
int a;
short c;
}d;
sizeof(d) == ? ; //在32位操作系统下为12字节,64位操作系统下也为12字节。

(每⼀次都开4个字节)
struct test2{
char a;
double b;
short c;
}d;
sizeof(d) == ? ;// 在32位操作系统下为16字节(每⼀次开4个字节),在64位操作系统下为24字节(每⼀次开8个字节)。

c语言结构体对齐规则

c语言结构体对齐规则

c语言结构体对齐规则
C语言结构体对齐规则是指在定义结构体时,编译器会按照一定的规则对结构体中的成员进行对齐,以保证结构体在内存中的存储方式是合理的。

这个规则是由编译器实现的,不同的编译器可能会有不同的实现方式。

结构体对齐的目的是为了提高内存访问的效率。

在计算机中,内存是以字节为单位进行存储的,而不是以位为单位。

因此,如果结构体中的成员没有按照一定的规则进行对齐,那么在访问结构体中的成员时,就需要进行多次内存访问,这会降低程序的执行效率。

C语言结构体对齐规则的实现方式是通过在结构体中插入一些空白字节来实现的。

具体来说,编译器会按照结构体中最大成员的大小进行对齐,也就是说,结构体中的每个成员都必须按照最大成员的大小进行对齐。

例如,如果结构体中最大的成员是一个int类型的变量,那么结构体中的每个成员都必须按照4字节进行对齐。

在进行结构体对齐时,编译器还会考虑结构体中成员的顺序。

具体来说,编译器会将结构体中相邻的成员进行合并,以减少空白字节的数量。

例如,如果结构体中有两个char类型的成员,那么编译器会将它们合并为一个2字节的成员,而不是分别对齐。

除了按照最大成员的大小进行对齐外,编译器还会考虑一些其他的因素,例如编译器的优化级别、目标平台的字节序等。

因此,在编
写程序时,我们应该尽量避免依赖结构体对齐的具体实现方式,以免出现不可预测的问题。

C语言结构体对齐规则是编译器为了提高程序执行效率而实现的一种机制。

在定义结构体时,我们应该遵循一定的规则,以保证结构体在内存中的存储方式是合理的。

同时,我们也应该尽量避免依赖结构体对齐的具体实现方式,以免出现不可预测的问题。

C语言中的数据对齐

C语言中的数据对齐

C语⾔中的数据对齐数据对齐的⽬的,是⽤空间换时间,提⾼效率.对齐本⾝并不难理解,但是有这么⼀个古怪的命令#pragma pack()存在,它可以⼈为指定按⼏个字节来对齐.有了这个命令,就让情况变得更加复杂了.⽹上有很多#pragma pack()命令的使⽤⽅法总结,但我不认为这个命令是必要的,应该尽量避免使⽤.如果你的代码⾥使⽤了#pragma pack(),会导致sizeof()取得预料外的值,导致程序出错.这个错误并不容易发现.#pragma pack()能让你的内存存储变紧凑,但会让sizeof()变得诡异,值得么?不值.(也许写程序传输协议时需要#pragma pack()来防⽌结构体中出现空洞?很牵强,我不认为这是必须的.)⼲脆,抛开#pragma pack()命令,简简单单来理解数据对齐吧.对齐表明了数据在内存中的存放⽅式,内存的最⼩单位是1字节,对齐长度为1说明数据可以存储在任何内存地址.对齐长度为2说明只能存放在能被2整除的内存地址.对齐长度是4只能存放在能被4整除的内存地址.对齐长度只能是2的幂,也就是1,2,4,8,16...数据对齐只会影响到结构体(或联合),归纳起来有如下两个规则:1.结构体外的数据类型,它们按照⾃⾝⼤⼩来对齐.⽐如char型对齐长度是1,int型对齐长度是4,double型对齐长度是8.(32位系统下⼀般是这样).2.结构体本⾝也有⼀个对齐长度,这个值是内部成员中⾃⾝对齐长度最⼤的那个值.结构体需按⾃⾝对齐长度对齐,换句话说,结构体⼤⼩必须是本⾝对齐长度的整数倍.根据上⾯两条,你就会算结构体的⼤⼩了.例1:struct A{char a;long b;char c;double d;};分析:sizeof(struct A)=24.a占⼀个字节,b对齐长度是4,所以a后⾯补三个字节的洞后再存b.紧跟着是c占⼀个字节,d的对齐长度是8,所以c后⾯补7个字节的洞后再存d.共24字节.struct A本⾝的对齐长度是8.例2:struct B{char a;char b;long c;double d;};分析:sizeof(struct B)=16.a占⼀个字节,b也占⼀个字节.c对齐长度是4,所以b后补两个字节洞后存c.d对齐长度是8,前⾯abc加起来恰好8字节,所以d可以紧跟c存放.共16字节.struct B本⾝的对齐长度是8.例3:struct C{ char a[123]; int b; float c; double d;};分析:sizeof(struct C)=144.a占123个字节,后补⼀个字节洞后存4字节的b,此时地址仍然能被4整除,所以紧跟着存4字节的c,⽬前总长度132,补4字节洞后存⼊8字节的d.总⼤⼩144字节.等等!有疑问!char a[123]的对齐长度是1还是123?是1.数组并⾮⼀种数据类型,这个数组的数据类型是char,char的对齐长度是1.所以,struct C的⾃⾝对齐长度是8,144是8的整数倍,没问题.例4:struct D{ struct x { char a; int b; float c; }X; int d; char e;};分析:sizeof(struct D)=20.先看struct x.a⼀个字节,补三个字节洞后跟4字节的b,之后是4字节的c.X的长度是12字节.struct x的⾃⾝对齐长度是4.再看struct D,X12字节,后跟4字节的d,之后是1个字节的e.struct D的⾃⾝对其长度是4(不是12,想⼀想吧).所以e后⾯要补三个字节洞.总长度是12+4+4=20.例5:struct E{ union y { char a; double b; int c; }Y; int d; double e;};分析:sizeof(struct E)=24.Y是⼀个联合,联合的特点是它会占⽤跟最⼤的内部成员相同的空间,double最⼤,所以union y的对齐长度是8.之后是4字节的d.8+4=12为了对齐后⾯是8字节的e,d后⾯要补4字节的洞.所以总长度是8+8+8=24.数据对齐基本就讲完了,描述不是特别清楚,还请见谅.在⽹上,看到有⼈提出了如下的疑问,请试试看能否替他解答⼀下呢?Struct A{char a,b;char arr[5];}//这个sizeof(A)=7.。

c语言结构体中的数组字节对齐

c语言结构体中的数组字节对齐

C语言结构体中的数组字节对齐在C语言中,结构体是一种用户自定义的数据类型,用于将不同类型的数据组合在一起。

结构体中常常包含多个成员变量,其中可能有数组类型的成员变量。

在结构体中使用数组时,需要了解数组字节对齐的概念和规则,以确保内存的最佳利用和访问的效率。

什么是字节对齐字节对齐是指在将数据存储在计算机内存中时,按照特定规则进行调整,以确保数据的存储和访问的效率。

字节对齐的规则可以对齐数据的起始地址或者数据的长度。

计算机中的数据存储是按照字节(Byte)来划分的,一个字节通常由8个二进制位组成。

字节对齐的主要目的是为了节省内存和提高访问效率。

在C语言中,结构体中的成员变量通常按照字节对齐的规则来排列。

C语言结构体中的数组字节对齐规则在C语言中,结构体中的数组字节对齐规则通常遵循以下原则:1.结构体的起始地址必须是所有成员变量所要求对齐方式的最小公倍数。

2.结构体中的每个成员变量的地址必须是它本身的大小的整数倍。

3.结构体的总大小必须是其最大成员变量大小的整数倍。

根据字节对齐规则,如果结构体中的成员变量的累计大小不是字节对齐的倍数,编译器会在成员变量之间添加填充字节,以满足对齐要求。

这些填充字节在结构体的占用空间中不可访问。

填充字节的目的是将后续成员变量的地址对齐,以提高内存访问效率。

数组字节对齐的示例为了更好地理解数组字节对齐的规则,我们来看一个示例。

#include <stdio.h>struct MyStruct {char c;int i;char arr[3];};int main() {struct MyStruct s;printf("sizeof(MyStruct) = %lu\n", sizeof(struct MyStruct));printf("sizeof(s.c) = %lu\n", sizeof(s.c));printf("sizeof(s.i) = %lu\n", sizeof(s.i));printf("sizeof(s.arr) = %lu\n", sizeof(s.arr));return 0;}输出结果:sizeof(MyStruct) = 12sizeof(s.c) = 1sizeof(s.i) = 4sizeof(s.arr) = 3在这个示例中,我们定义了一个包含一个字符类型变量、一个整型变量和一个长度为3的字符数组的结构体MyStruct。

C语言字节对齐

C语言字节对齐

C语言字节对齐字节对齐的由来程序在运行时会将数据临时存放在内存中,芯片内核需要对这些数据进行计算,不断的读取内存以获得数据,并将计算结果写入内存。

计算机体系经过若干年的发展,最终确定了以8bits作为其基本的存储单元——byte(字节),这是每个地址所对应的最小访问单元,在C语言中对应一个char型的变量。

下图为芯片内核访问内存的示意图。

芯片内核通过控制总线控制内存的动作,通过地址总线告知内存地址,数据总线上出现交互的数据。

图1访问内存示意图假设上图是8位机的示意图,那么数据总线的宽度是8bits,由8根数据线组成,这样芯片内核与内存之间一次就可以同时交换8个bits的数据,正好是一个字节。

图中右侧的每个小格子代表一个存储地址,对应一个字节。

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

char data[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]中,芯片内核将控制总线置为写信号,将地址总线置为0x101,将数据总线置为3,内存接收到这些信号后,就会将数据3存入到其内部0x101地址中,完成本次操作。

c语言结构体对齐方式

c语言结构体对齐方式

c语言结构体对齐方式
在C语言中,结构体的对齐方式可以通过指定特定的编译器选项或者在结构体定义中使用特定的关键字来控制。

首先,大部分现代编译器都支持指定结构体对齐的编译器选项。

例如,在GCC编译器中,可以使用-fpack-struct选项来指定结构体的对齐方式。

该选项可以接受一个整数值,表示结构体对齐的字节数。

例如,-fpack-struct=4将使结构体按照4字节对齐。

另外,在结构体定义中,可以使用#pragma pack指令来指定结构体的对齐方式。

例如:
c复制代码:
#pragma pack(push, 1)
struct MyStruct {
int a;
char b;
short c;
};
#pragma pack(pop)
在上面的代码中,#pragma pack(push, 1)将把当前结构体的对齐方式设置为1字节对齐,然后定义结构体,最后使用
#pragma pack(pop)恢复原来的对齐方式。

需要注意的是,结构体的对齐方式会影响到结构体的大小和内存布局。

因此,在选择结构体的对齐方式时,需要根据实际情况进行权衡和选择。

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字节对界),其偏移地址为0char x2; // 成员x2为char型(其起始地址必须1字节对界,其偏移地址为1float x3; // 成员x3为float型(其起始地址必须4字节对界),编译器在x2和x3之间填充了两个空字节,其偏移地址为4char x4; // 成员x4为char型(其起始地址必须1字节对界),其偏移地址为8};因为Test结构体中,最⼤的成员为flaot x3,因些此结构体的⾃然对界条件为4字节对齐。

则结构体长度就为12字节,内存布局为1100 1111 1000。

例⼦2:#include <stdio.h>//#pragma pack(2)typedef struct{int aa1; //4个字节对齐 1111char bb1;//1个字节对齐 1short cc1;//2个字节对齐 011char dd1; //1个字节对齐 1} testlength1;int length1 = sizeof(testlength1); //4个字节对齐,占⽤字节1111 1011 1000,length = 12typedef struct{char bb2;//1个字节对齐 1int aa2; //4个字节对齐 01111short cc2;//2个字节对齐 11char dd2; //1个字节对齐 1} testlength2;int length2 = sizeof(testlength2); //4个字节对齐,占⽤字节1011 1111 1000,length = 12typedef struct{char bb3; //1个字节对齐 1char dd3; //1个字节对齐 1int aa3; //4个字节对齐 001111short cc23//2个字节对齐 11} testlength3;int length3 = sizeof(testlength3); //4个字节对齐,占⽤字节1100 1111 1100,length = 12typedef struct{char bb4; //1个字节对齐 1char dd4; //1个字节对齐 1short cc4;//2个字节对齐 11int aa4; //4个字节对齐 1111} testlength4;int length4 = sizeof(testlength4); //4个字节对齐,占⽤字节1111 1111,length = 8int main(void){printf("length1 = %d.\n",length1);printf("length2 = %d.\n",length2);printf("length3 = %d.\n",length3);printf("length4 = %d.\n",length4);return0;}改变缺省的对界条件(指定对界)· 使⽤伪指令#pragma pack (n),C编译器将按照n个字节对齐。

内嵌结构体的对齐方式

内嵌结构体的对齐方式

内嵌结构体的对齐方式
内嵌结构体的对齐方式是根据包含它的结构体的对齐方式来确定的。

在C语言中,默认的对齐方式是按照结构体中的成员顺序逐个对齐,每个成员的对齐方式由其类型决定。

常见的对齐方式有:
- 对于字符类型(char),按照字节对齐,即对齐值为1。

- 对于短整型(short),根据系统架构不同,可能按照2字节对齐或4字节对齐。

- 对于整型(int)和浮点型(float),通常按照4字节对齐。

- 对于长整型(long)和双精度浮点型(double),通常按照8字节对齐。

当结构体中出现内嵌结构体时,内嵌结构体的对齐方式受到外层结构体的对齐方式的影响。

即内嵌结构体的起始地址必须是外层结构体对齐值的整数倍。

例如,考虑以下代码示例:
```c
struct InnerStruct {
char c;
int i;
};
struct OuterStruct {
char a;
struct InnerStruct inner;
int b;
};
```
在这个例子中,OuterStruct中包含了InnerStruct。

根据编译器
的对齐规则,如果char是1字节对齐,int是4字节对齐,那
么OuterStruct的对齐值将是4。

因此,编译器将使得InnerStruct的起始地址必须是4的整数倍。

实际上,每个编译器可能会有不同的对齐规则和默认对齐方式,可以通过编译器提供的特定选项来调整对齐方式。

对于特定的对齐需求,还可以使用预编译指令来设置结构体的对齐方式。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

内存中结构体的内存对齐
一、字节对齐作用和原因:
对齐的作用和原因:各个硬件平台对存储空间的处理上有很大的不同。

一些平台对某些特定类型的数据只能从某些特定地址开始存取。

比如有些架构的CPU在访问一个没有进行对齐的变量的时候会发生错误,那么在这种架构下编程必须保证字节对齐,其他平台可能没有这种情况,但是最常见的是如果不按照适合其平台要求对数据存放进行对齐,会在存取效率上带来损失。

比如有些平台每次读都是从偶地址开始,如果一个int型(假设为32位系统)如果存放在偶地址开始的地方,那么一个读周期就可以读出这32bit,而如果存放在奇地址开始的地方,就需要2个读周期,并对两次读出的结果的高低字节进行拼凑才能得到该32bit 数据,显然在读取效率上下降很多。

二、字节对齐规则:
四个重要的概念:
1.数据类型自身的对齐值:对于char型的数据,其自身对齐值为1,对于short型为2,对于int,float,double类型,其自身对齐值为4个字节。

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

3.指定对齐值:#pragma pack (value)时指定的对齐value。

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

补充:
1).每个成员分别按自己的方式对齐,并能最小化长度。

2).复杂类型(如结构)的默认对齐方式是它最长的成员的对齐方式,这样在成员是复杂类型时,可以最小化长度。

3).对齐后的长度必须是成员中最大的对齐参数的整数倍,这样在处理数组时可以保证每一项都边界对齐。

#pragma pack(1)
struct test
{
static int a; //static var
double m4;
char m1;
int m3;
} #pragma pack()
//sizeof(test)=13;
Class test1{ };
//sizeof(test1)=1;
/* 注明:
1、结构或者类中的静态成员不对结构或者类的大小产生影响,因为静态变量的存储位置与结构或者类的实例地址无关;
2、没有成员变量的结构或类的大小为1,因为必须保证结构或类的每一个实例在内存中都有唯一的地址。

*/
#pragma pack(1)
struct test
{
static int a; //static var
double m4;
char m1;
int m3;
}
#pragma pack()
//sizeof(test)=13;
Class test1{ };
//sizeof(test1)=1;
/* 注明:
1、结构或者类中的静态成员不对结构或者类的大小产生影响,因为静态变量的存储位置与结构或者类的实例地址无关;
2、没有成员变量的结构或类的大小为1,因为必须保证结构或类的每一个实例在内存中都有唯一的地址。

*/
示例://分析下面的例子C:
//
#pragma pack (2) /*指定按2字节对齐*/
struct C
{
char b;
int a;
short c;
};
#pragma pack () //恢复对齐状态
/*
第一个变量b的自身对齐值为1,指定对齐值为2,所以,其有效对齐值为1,假设C从0x0000开始,那么b存放在0x0000,符合0x0000%1 = 0;
第二个变量,自身对齐值为4,指定对齐值为2,所以有效对齐值为2,所以顺序存放在0x0002、0x0003、0x0004、0x0005四个连续的字节空间中,符合0x0002%2=0。

第三个变量c的自身对齐值为2,所以有效对齐值为2,顺序在0x0006、0x0007中,符合
0x0006%2=0。

所以从0x0000到0x0007共八字节存放的是struct C的变量。

又struct C的自身对齐值为4,所以struct C的有效对齐值为2。

又8%2=0,struct C只占用0x0000到0x0007的八个字节。

所以sizeof(struct C)=8。

如果把上面的#pragma pack(2)改为#pragma pack(4),那么我们可以得到结构的大小为12。

*/
//再看下面这个例子
//
#pragma pack(8)
struct S1
{
char a;
long b;
};
struct S2 {
char c;
struct S1 d;
long long e;
};
#pragma pack()
sizeof(S2)结果为24.
/*
S1中:
成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐; 成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8;
S2 中:
c和S1中的a一样,按1字节对齐,
d 是个结构,它是8个字节,它按什么对齐呢?对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个,S1的就是4.所以,成员d就是按4字节对齐.
成员e是8个字节,它是默认按8字节对齐,和指定的一样,所以它对到8字节的边界上,这时,已经使用了12个字节了,所以又添加了4个字节的空,从第16个字节开始放置成员e;
长度为24,已经可以被8(成员e按8字节对齐)整除.一共使用了24个字节.
a b
S1的内存布局:11**,1111,
c S1.a S1.b d
S2的内存布局:1***,11**,1111,****
*/
//再看下面这个例子
//
#pragma pack(8)
struct S1
{
char a;
long b;
};
struct S2 {
char c;
struct S1 d;
long long e;
};
#pragma pack()
sizeof(S2)结果为24.
/*
S1中:
成员a是1字节默认按1字节对齐,指定对齐参数为8,这两个值中取1,a按1字节对齐; 成员b是4个字节,默认是按4字节对齐,这时就按4字节对齐,所以sizeof(S1)应该为8;
S2 中:
c和S1中的a一样,按1字节对齐,
d 是个结构,它是8个字节,它按什么对齐呢?对于结构来说,它的默认对齐方式就是它的所有成员使用的对齐参数中最大的一个,S1的就是4.所以,成员d就是按4字节对齐.
成员e是8个字节,它是默认按8字节对齐,和指定的一样,所以它对到8字节的边界上,这时,已经使用了12个字节了,所以又添加了4个字节的空,从第16个字节开始放置成员e;
长度为24,已经可以被8(成员e按8字节对齐)整除.一共使用了24个字节.
a b
S1的内存布局:11**,1111,
c S1.a S1.b d
S2的内存布局:1***,11**,1111,****
*/
三、针对字节对齐,我们在编程中如何考虑?
如果在编程的时候要考虑节约空间的话,那么我们只需要假定结构的首地址是0,然后各个变量按照上面的原则进行排列即可,基本的原则就是把结构中的变量按照类型大小从小到大声明,尽量减少中间的填补空间。

还有一种就是为了以空间换取时间的效率,我们显示的进行填补空间进行对齐,比如:有一种使用空间换时间做法是显式的插入reserved成员:
struct A
{
char a;
char reserved[3]; //使用空间换时间
int b;
};
reserved成员对我们的程序没有什么意义,它只是起到填补空间以达到字节对齐的目的,当然即使不加这个成员通常编译器也会给我们自动填补对齐,我们自己加上它只是起到显示的提醒作用。

四、字节对齐可能带来的隐患
代码中关于对齐的隐患,很多是隐式的。

比如在强制类型转换的时候。

例如:
unsigned int i = 0x;
unsigned char *p = NULL;
unsigned short *p1 = NULL;
p=&i;
*p=0x00;
p1=(unsigned short*)(p+1);
*p1=0x0000;
最后两行代码,从奇数边界去访问unsigned short型变量,显然不符合对齐的规定。

在X86上,类似的操作只会影响效率,但是在MIPS或者sparc上,可能就是一个error,因为它们要求字节必须对齐。

五、如何查找与字节对齐方面的问题
如果出现对齐或者赋值问题首先查看
1.编译器设置的对齐值
2.看这种体系本身是否支持非对齐访问
3.如果支持看设置了对齐与否,如果没有则看访问时需要加某些特殊的修饰来标志其特殊访问操作。

相关文档
最新文档