C语言内存对齐
使用C语言技术进行内存管理的方法

使用C语言技术进行内存管理的方法使用C语言进行内存管理的方法在编程中,内存管理是一个非常重要的问题。
合理地管理内存可以提高程序的性能和效率,避免内存泄漏和内存溢出等问题。
本文将介绍一些使用C语言技术进行内存管理的方法。
1. 动态内存分配动态内存分配是C语言中常用的内存管理技术之一。
通过动态内存分配,我们可以在程序运行时根据需要动态地分配和释放内存。
C语言提供了几个函数来进行动态内存分配,如malloc、calloc和realloc。
其中,malloc函数用于分配指定大小的内存空间,calloc函数用于分配指定数量的相同大小的内存空间,并将其初始化为0,realloc函数用于重新分配已分配内存的大小。
2. 内存释放动态分配的内存在使用完毕后必须及时释放,以免造成内存泄漏。
C语言中使用free函数来释放动态分配的内存。
当不再需要使用某块内存时,应该调用free函数将其释放,以便系统可以重新利用该内存。
3. 内存回收除了手动释放内存外,C语言还提供了一种自动回收内存的机制,即垃圾回收。
垃圾回收是一种自动管理内存的技术,它会自动检测和回收不再使用的内存,避免程序员手动释放内存的繁琐工作。
C语言中并没有内置的垃圾回收机制,但可以使用第三方库或框架来实现自动内存回收。
4. 内存池内存池是一种用于管理内存的数据结构,它可以提高内存分配和释放的效率。
内存池将一块较大的内存空间划分为多个小块,每次分配和释放内存时,只需要在内存池中进行操作,而不需要频繁地向系统申请和释放内存。
内存池可以减少内存碎片和系统调用的次数,提高程序的性能。
5. 内存对齐内存对齐是一种对齐内存访问的规范,可以提高内存访问的效率。
在C语言中,结构体和数组的内存对齐是由编译器自动完成的,但对于动态分配的内存,我们需要手动进行内存对齐。
可以使用C语言的一些特性来实现内存对齐,如使用宏定义来指定对齐方式,使用特定的数据类型来保证内存对齐。
6. 内存检测工具为了帮助程序员检测和调试内存相关的问题,C语言提供了一些内存检测工具,如valgrind和GDB。
c语言申请内存的函数 对齐

c语言申请内存的函数对齐C语言是一种广泛应用于系统编程和嵌入式开发的编程语言。
在C 语言中,内存管理是一个重要的概念,而申请内存的函数对齐则是其中的一个关键方面。
在C语言中,我们可以使用malloc函数来动态申请内存。
malloc 函数的原型如下:```cvoid* malloc(size_t size);```其中,size_t是一个无符号整数类型,表示要申请的内存大小(以字节为单位)。
malloc函数会在堆内存中分配一块指定大小的连续内存,并返回一个指向该内存块起始地址的指针。
然而,对齐是一个需要考虑的重要问题。
对齐是指内存分配时,数据在内存中的存放位置是否按照一定的规则进行对齐。
对齐的目的是提高内存访问的效率,特别是对于一些硬件平台而言。
在C语言中,对齐的规则是由编译器和硬件平台共同决定的。
通常情况下,编译器会根据数据类型的大小和硬件平台的要求来进行对齐。
对齐的方式可以是字节对齐、字对齐或者其他方式。
为了实现对齐,C语言提供了一个特殊的对齐属性——alignas。
alignas属性可以用来指定变量或结构体的对齐方式。
例如,我们可以使用alignas(4)来指定一个变量按照4字节对齐。
除了使用alignas属性外,C语言还提供了一些与对齐相关的函数和宏。
其中,最常用的是aligned_alloc函数和alignof宏。
aligned_alloc函数可以用来申请对齐的内存。
它的原型如下:```cvoid* aligned_alloc(size_t alignment, size_t size);```其中,alignment表示对齐的字节数,size表示要申请的内存大小。
aligned_alloc函数会在堆内存中分配一块对齐的内存,并返回一个指向该内存块起始地址的指针。
alignof宏可以用来获取指定类型的对齐方式。
它的用法如下:```calignof(type)```其中,type表示要获取对齐方式的类型。
c语言结构体对齐规则

c语言结构体对齐规则C语言中的结构体是一种将多个数据项组合成一个整体的数据类型。
在定义结构体时,需要考虑如何进行内存对齐,以保证数据访问的正确性和效率。
本文将介绍C语言结构体的对齐规则。
结构体内存对齐规则主要涉及两个概念:对齐边界和填充字节。
对齐边界指的是数据在内存中的对齐位置,它必须是该数据类型大小的整数倍。
填充字节是指在数据与对齐边界之间补充的字节,以满足对齐要求。
C语言结构体对齐规则如下:1. 结构体内的第一个数据成员放在地址最低的位置,后面的数据成员按照声明顺序依次放置。
2. 结构体的总大小必须是其包含的所有数据成员大小的整数倍,如果不是,则在最后一个数据成员后面填充字节。
3. 结构体的对齐边界为其中最大的数据成员大小。
即结构体的起始地址必须是最大数据成员大小的整数倍。
4. 当结构体中包含的数据成员不同类型时,按照其大小从大到小进行排列。
5. 如果结构体中包含的数据成员中有某个成员的大小超过了当前的对齐边界,则需要进行填充字节,以保证下一个数据成员的对齐要求。
下面通过几个例子来说明内存对齐规则的应用:例一:struct student{char name[10];int age;float score;};使用sizeof计算结构体大小得到:24 (可以想象,不加对齐的话只有12个字节)对齐后:struct student{char name[10]; 10char fill[2]; fillint age; 4float score; 4};例二:struct person{char gender;short height;int id;};使用sizeof计算结构体大小得到:8 (在32位架构上)对齐后:struct person{char gender; 1char fill[1]; fillshort height; 2int id; 4};例三:struct fraction{int numerator;int denominator;char symbol;};使用sizeof计算结构体大小得到:12 (在32位架构上)对齐后:struct fraction{int numerator; 4int denominator; 4char symbol; 1char fill; fill};总结:内存对齐是为了保证数据访问的效率和正确性,不能忽视。
c语言结构体对齐规则

c语言结构体对齐规则
C语言结构体对齐规则是指在定义结构体时,编译器会按照一定的规则对结构体中的成员进行对齐,以保证结构体在内存中的存储方式是合理的。
这个规则是由编译器实现的,不同的编译器可能会有不同的实现方式。
结构体对齐的目的是为了提高内存访问的效率。
在计算机中,内存是以字节为单位进行存储的,而不是以位为单位。
因此,如果结构体中的成员没有按照一定的规则进行对齐,那么在访问结构体中的成员时,就需要进行多次内存访问,这会降低程序的执行效率。
C语言结构体对齐规则的实现方式是通过在结构体中插入一些空白字节来实现的。
具体来说,编译器会按照结构体中最大成员的大小进行对齐,也就是说,结构体中的每个成员都必须按照最大成员的大小进行对齐。
例如,如果结构体中最大的成员是一个int类型的变量,那么结构体中的每个成员都必须按照4字节进行对齐。
在进行结构体对齐时,编译器还会考虑结构体中成员的顺序。
具体来说,编译器会将结构体中相邻的成员进行合并,以减少空白字节的数量。
例如,如果结构体中有两个char类型的成员,那么编译器会将它们合并为一个2字节的成员,而不是分别对齐。
除了按照最大成员的大小进行对齐外,编译器还会考虑一些其他的因素,例如编译器的优化级别、目标平台的字节序等。
因此,在编
写程序时,我们应该尽量避免依赖结构体对齐的具体实现方式,以免出现不可预测的问题。
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++结构体字节对齐 pack规则

在C语言中,结构体的字节对齐(pack规则)是指结构体成员变量在内存中的存储方式。
结构体成员变量的对齐方式会影响程序的性能和内存占用。
为了提高访问速度,编译器会根据一定的规则对结构体成员变量进行对齐。
在C语言中,可以使用`#pragma pack(n)`指令来设置结构体的字节对齐规则,其中n表示对齐的字节数。
例如:```c#include <stdio.h>#pragma pack(2) // 设置结构体成员变量按照2字节对齐typedef struct {char a;int b;short c;} MyStruct;int main() {MyStruct ms;printf("sizeof(MyStruct) = %lu", sizeof(ms)); // 输出结果为8,因为设置了2字节对齐,所以每个成员变量都会补齐1字节,最后总大小为8字节return 0;}```如果不使用`#pragma pack`指令,编译器会默认按照最大成员变量的字节数进行对齐。
例如:```c#include <stdio.h>typedef struct {char a;int b;short c;} MyStruct;int main() {MyStruct ms;printf("sizeof(MyStruct) = %lu", sizeof(ms)); // 输出结果可能为12,因为默认按照4字节对齐,所以每个成员变量都会补齐3字节,最后总大小为12字节return 0; }```。
内存对齐的技巧
内存对齐的技巧
内存对齐是一种优化技术,它可以提高数据在内存中的访问速度,减少内存访问的时间。
下面是一些内存对齐的技巧:
1. 使用对齐的数据类型:在定义结构体时,使用对齐的数据类型,例如使用32位机器上的32位整数,而不是16位整数。
2. 将大的数据类型放在前面:在定义结构体时,将大的数据类型放在前面,这样可以最大程度地减少内存碎片。
3. 使用字节对齐指令:一些编程语言和编译器提供了字节对齐的指令,可以在编译时对结构体进行字节对齐。
4. 使用特定的编译选项:在编译程序时,可以设置特定的编译选项,例如使用-malign-double选项来告诉编译器以双字对齐浮点数。
5. 避免结构体的嵌套:结构体的嵌套会增加内存的存取时间,可以尽量避免结构体的嵌套使用。
6. 了解特定平台的对齐规则:不同的平台有不同的对齐规则,了解特定平台的对齐规则可以帮助进行更好的内存对齐。
这些技巧可以帮助程序员优化内存对齐,提高程序的性能和执行效率。
c语言内存对齐系数
c语言内存对齐系数C语言内存对齐系数在C语言中,内存对齐是指将结构体或联合体的成员按照一定的规则进行排列,以便于提高程序的运行效率。
内存对齐系数是用来描述对齐规则的一个参数,它决定了结构体或联合体成员在内存中的对齐方式。
1. 什么是内存对齐系数内存对齐系数是一个整数,表示结构体或联合体成员在内存中的对齐方式。
通常情况下,内存对齐系数是编译器根据目标平台的特点自动确定的,但也可以通过编译器的特殊选项来手动指定。
内存对齐系数越大,成员在内存中的对齐方式越严格。
2. 为什么需要内存对齐内存对齐是为了提高程序的运行效率和访问速度。
当结构体或联合体中的成员按照对齐规则排列时,可以减少内存访问的次数,提高内存读写效率。
此外,一些特殊的硬件平台对于数据的对齐要求非常严格,不满足对齐要求的数据可能导致硬件异常或错误。
3. 内存对齐的规则内存对齐规则是由编译器根据目标平台的特点制定的。
通常情况下,对齐规则遵循以下几个原则:- 结构体或联合体的首地址必须是其最宽基本类型成员大小的整数倍。
- 结构体或联合体的每个成员相对于结构体或联合体首地址的偏移量必须是该成员大小的整数倍。
- 结构体或联合体的总大小必须是其最宽基本类型成员大小的整数倍。
4. 内存对齐的影响内存对齐会影响程序的内存占用和性能。
由于对齐规则的存在,结构体或联合体的大小可能会比成员大小的总和要大,这会增加程序的内存占用。
但是,内存对齐可以提高内存访问的效率,尤其是对于大量的结构体或联合体访问操作,可以明显提高程序的性能。
5. 如何控制内存对齐可以通过编译器的特殊选项来手动控制内存对齐。
例如,在GCC编译器中,可以使用#pragma pack(n)来设置内存对齐系数为n。
其中,n可以是1、2、4、8等整数,表示对齐系数为1字节、2字节、4字节、8字节等。
需要注意的是,手动设置内存对齐系数可能会影响程序的性能和可移植性,应谨慎使用。
6. 示例下面以一个示例来说明内存对齐的作用。
c语言边界对齐
c语言边界对齐C语言中的边界对齐是指在内存中分配变量时,将变量的起始地址对齐到特定的边界。
边界对齐可以提高内存访问的效率,减少内存访问时间。
在C语言中,边界对齐是由编译器自动完成的。
编译器会根据变量的类型和平台的要求来确定变量的对齐方式。
一般来说,基本数据类型(如int、float、char等)的对齐方式是按照其大小进行对齐,即按照4字节或8字节等进行对齐。
例如,在32位系统上,int类型通常是4字节大小,所以int类型的变量会被对齐到4字节边界。
而在64位系统上,int类型通常是8字节大小,所以int类型的变量会被对齐到8字节边界。
结构体和联合体中的成员也需要进行边界对齐。
结构体和联合体中成员的对齐方式取决于成员中占用空间最大的数据类型。
例如,如果结构体中有一个成员是double类型(占用8字节),那么整个结构体将被对齐到8字节边界。
边界对齐可以提高内存访问效率的原因是因为当变量对齐到边界时,CPU可以更快地访问内存中的数据。
如果变量没有对齐到边界,CPU可能需要进行额外的操作来访问数据,这会增加内存访问的时间。
在某些情况下,我们可能需要手动控制变量的对齐方式。
在C语言中,可以使用特定的编译指令来控制变量的对齐方式。
例如,可以使用#pragma pack指令来设置结构体和联合体成员的对齐方式。
总之,边界对齐是C语言中一个重要的概念,它可以提高内存访问效率。
编译器会根据变量的类型和平台要求自动完成边界对齐。
在某些情况下,我们也可以手动控制变量的对齐方式。
了解和正确使用边界对齐是写出高效、可靠的C语言程序的关键之一。
cstatic对齐方式
cstatic对齐方式摘要:一、前言二、cstatic 对齐方式的介绍1.cstatic 对齐方式的定义2.cstatic 对齐方式的作用三、cstatic 对齐方式与编程语言的关系1.C 语言中的对齐规则2.C++语言中的对齐规则四、cstatic 对齐方式在实际编程中的应用1.提高代码的可读性和可维护性2.优化程序的性能五、总结正文:一、前言在编程中,对齐方式是一个重要的概念,它影响着代码的结构和性能。
cstatic 对齐方式是其中一种对齐方式,被广泛应用于各种编程语言中。
本文将详细介绍cstatic 对齐方式的相关知识。
二、cstatic 对齐方式的介绍1.cstatic 对齐方式的定义cstatic 对齐方式是指编译器在分配变量内存空间时,按照该变量类型的大小,在内存中进行对齐。
这种方式可以保证变量在内存中的地址与其大小相对应,使得内存空间的利用率更高。
2.cstatic 对齐方式的作用cstatic 对齐方式的主要作用是提高内存空间的利用率,同时使得程序的运行效率更高。
通过对齐,可以减少内存空间的浪费,降低程序的内存占用。
三、cstatic 对齐方式与编程语言的关系1.C 语言中的对齐规则在C 语言中,变量的地址与其大小是无关的,这就导致了内存空间的浪费。
为了解决这个问题,编译器会按照cstatic 对齐方式对变量进行对齐。
这样,变量的地址与其大小相等,从而提高了内存空间的利用率。
2.C++语言中的对齐规则在C++语言中,类的成员变量默认按照cstatic 对齐方式进行对齐。
这种方式可以保证类的成员变量在内存中的地址与其大小相对应,使得内存空间的利用率更高。
四、cstatic 对齐方式在实际编程中的应用1.提高代码的可读性和可维护性通过使用cstatic 对齐方式,可以使代码的结构更加清晰,提高代码的可读性和可维护性。
2.优化程序的性能cstatic 对齐方式可以减少内存空间的浪费,降低程序的内存占用,从而优化程序的性能。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
解析C语言结构体对齐(内存对齐问题)
C语言结构体对齐也是老生常谈的话题了。
基本上是面试题的必考题。
内容虽然很基础,但一不小心就会弄错。
写出一个struct,然后sizeof,你会不会经常对结果感到奇怪?sizeof的结果往往都比你声明的变量总长度要大,这是怎么回事呢?
开始学的时候,也被此类问题困扰很久。
其实相关的文章很多,感觉说清楚的不多。
结构体到底怎样对齐?
有人给对齐原则做过总结,具体在哪里看到现在已记不起来,这里引用一下前人的经验(在没有#pragma pack宏的情况下):
原则1、数据成员对齐规则:结构(struct或联合union)的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员存储的起始位置要从该成员大小的整数倍开始(比如int在32位机为4字节,则要从4的整数倍地址开始存储)。
原则2、结构体作为成员:如果一个结构里有某些结构体成员,则结构体成员要从其内部最大元素大小的整数倍地址开始存储。
(struct a里存有struct b,b里有char,int,double等元素,那b应该从8的整数倍开始存储。
)
原则3、收尾工作:结构体的总大小,也就是sizeof的结果,必须是其内部最大成员的整数倍,不足的要补齐。
这三个原则具体怎样理解呢?我们看下面几个例子,通过实例来加深理解。
例1:struct {
short a1;
short a2;
short a3;
}A;
struct{
long a1;
short a2;
}B;
sizeof(A) = 6; 这个很好理解,三个short都为2。
sizeof(B) = 8; 这个比是不是比预想的大2个字节?long为4,short为2,整个为8,因为原则3。
例2:struct A{
int a;
char b;
short c;
};
struct B{
char b;
int a;
short c;
};
sizeof(A) = 8; int为4,char为1,short为2,这里用到了原则1和原则3。
sizeof(B) = 12; 是否超出预想范围?char为1,int为4,short为2,怎么会是12?还是原则1和原则3。
深究一下,为什么是这样,我们可以看看内存里的布局情况。
a b c
A的内存布局:1111, 1*, 11
b a c
B的内存布局:1***, 1111, 11**
其中星号*表示填充的字节。
A中,b后面为何要补充一个字节?因为c为short,其起始位置要为2的倍数,就是原则1。
c的后面没有补充,因为b和c正好占用4个字节,整个A占用空间为4的倍数,也就是最大成员int类型的倍数,所以不用补充。
B中,b是char为1,b后面补充了3个字节,因为a是int为4,根据原则1,起始位置要为4的倍数,所以b后面要补充3个字节。
c后面补充两个字节,根据原则3,整个B占用空间要为4的倍数,c后面不补充,整个B的空间为10,不符,所以要补充2个字节。
再看一个结构中含有结构成员的例子:
例3:struct A{
int a;
double b;
float c;
};
struct B{
char e[2];
int f;
double g;
short h;
struct A i;
};
sizeof(A) = 24; 这个比较好理解,int为4,double为8,float为4,总长为8的倍数,补齐,所以整个A为24。
sizeof(B) = 48; 看看B的内存布局。
e f g h i
B的内存布局:11* *, 1111, 11111111, 11 * * * * * *, 1111* * * *, 11111111, 1111 * * * *
i其实就是A的内存布局。
i的起始位置要为24的倍数,所以h后面要补齐。
把B的内存布局弄清楚,有关结构体的对齐方式基本就算掌握了。
以上讲的都是没有#pragma pack宏的情况,如果有#pragma pack宏,对齐方式按照宏的定义来。
比如上面的结构体前加#pragma pack(1),内存的布局就会完全改变。
sizeof(A) = 16; sizeof(B) = 32;
有了#pragma pack(1),内存不会再遵循原则1和原则3了,按1字节对齐。
没错,这不是理想中的没有内存对齐的世界吗。
a b c
A的内存布局:1111, 11111111, 1111
e f g h i
B的内存布局:11, 1111, 11111111, 11 , 1111, 11111111, 1111
那#pragma pack(2)的结果又是多少呢?#pragma pack(4)呢?留给大家自己思考吧,相信没有问题。
还有一种常见的情况,结构体中含位域字段。
位域成员不能单独被取sizeof值。
C99规
定int、unsigned int和bool可以作为位域类型,但编译器几乎都对此作了扩展,允许其它类型类型的存在。
使用位域的主要目的是压缩存储,其大致规则为:
1) 如果相邻位域字段的类型相同,且其位宽之和小于类型的sizeof大小,则后面的字段将紧邻前一个字段存储,直到不能容纳为止;
2) 如果相邻位域字段的类型相同,但其位宽之和大于类型的sizeof大小,则后面的字段将从新的存储单元开始,其偏移量为其类型大小的整数倍;
3) 如果相邻的位域字段的类型不同,则各编译器的具体实现有差异,VC6采取不压缩方式,Dev-C++采取压缩方式;
4) 如果位域字段之间穿插着非位域字段,则不进行压缩;
5) 整个结构体的总大小为最宽基本类型成员大小的整数倍。
还是让我们来看看例子。
例4:struct A{
char f1 : 3;
char f2 : 4;
char f3 : 5;
};
a b c
A的内存布局:111, 1111 *, 11111 * * *
位域类型为char,第1个字节仅能容纳下f1和f2,所以f2被压缩到第1个字节中,而f3只能从下一个字节开始。
因此sizeof(A)的结果为2。
例5:struct B{
char f1 : 3;
short f2 : 4;
char f3 : 5;
};
由于相邻位域类型不同,在VC6中其sizeof为6,在Dev-C++中为2。
例6:struct C{
char f1 : 3;
char f2;
char f3 : 5;
};
非位域字段穿插在其中,不会产生压缩,在VC6和Dev-C++中得到的大小均为3。
考虑一个问题,为什么要设计内存对齐的处理方式呢?如果体系结构是不对齐的,成员将会一个挨一个存储,显然对齐更浪费了空间。
那么为什么要使用对齐呢?体系结构的对齐和不对齐,是在时间和空间上的一个权衡。
对齐节省了时间。
假设一个体系结构的字长为w,那么它同时就假设了在这种体系结构上对宽度为w的数据的处理最频繁也是最重要的。
它的设计也是从优先提高对w位数据操作的效率来考虑的。
有兴趣的可以google一下,人家就可以跟你解释的,一大堆的道理。
最后顺便提一点,在设计结构体的时候,一般会尊照一个习惯,就是把占用空间小的类型排在前面,占用空间大的类型排在后面,这样可以相对节约一些对齐空间。