本文主要是介绍结构体的内存分配机制,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
首先,结构在C语言中也是一种数据类型,叫做聚组类型(还包括数组)。他和其他的数据类型是一样的,在定义一个结构体的时候,系统并不会为他真正的分配内存空间(定义的结构体变量要在编译的阶段才分配空间,而结构体指针要显示的使用malloca来分配空间),也就是说,在定义结构体这种数据类型的时候是不会分配内存空间的,只有在定义变量的时候,才会分配。
下面是摘自百度百科 对结构题存储的三点:
1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;
2) 结构体每个成员相对于结构体首地址的偏移量都是成员大小的整数倍,如有需要编译器会 在成员之间加上填充字节;
3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节
下面是来自《c和指针》的介绍
struct s1{
char a;
int b;
char c;
};
首先,结构体在存储的时候,结构体的首地址必须能够被其中最宽数据类型整除。(在s1中,最宽数据类型为int,在32位系统中为4Byte),
其次,参照第二条,第一个数据时char(已经保证了,结构的起始地址是4的整数倍),存储一个char,占一个Byte,要保证下一个int的存储起始地址是4的整数倍,所以要在char后面填充三个Byte,然后在存储第三个数据。
第三,最后一个也是char类型,他就占一个Byte,肯定是他存储位置的整数倍,最后参照第三条,结构体的总大小为最宽数据类型的整数倍,所以会在第二个char之后再填充三个Byte。
这样的话,总共占据的空间是1+3+4+1+3 = 12(红色为填充字符)
【但是】,调换一下结构中数据成员的顺序
struct s1{
int b;
char a;
char c;
};
同样地分析4+1+1+2 = 8
相比之下,存储空间的效率提高33%。
以下是系统对结构体的内存分配的详细介绍:
1、结构体变量的首地址是结构体中最宽数据类型的整数倍。
编译器在给结构体开辟空间时,首先找到结构体中最宽的基本数据类型,然后寻找内存地址能是该基本数据类型的整倍的位置,作为结构体的首地址。
2、结构体每个成员相对于结构体首地址的偏移量(offset)都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节。
为结构体的一个成员开辟空间之前,编译器首先检查预开辟空间的首地址相对于结构体首地址的偏移是否是本成员的整数倍,若是,则存放本成员,反之,则在本成员和上一个成员之间填充一定的字节,以达到整数倍的要求,也就是将预开辟空间的首地址后移几个字节。
3、结构体的总大小为结构体中最宽基本数据成员的整数倍。如有需要,编译器将会在结构体的添加填充字符。
4、结构体中的数据成员按照所占空间从大到小的顺序来排列的话,这样存储空间就会得以提高。
4、现在对四条进行修正。在组织数据结构的数据成员的时候,可以将相同类型的成员放在一起,这样就减少了编译器为了对齐而添加的填充字符。
这篇关于结构体的内存分配机制的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!