目录
- 1、结构体内存对齐
- 2、共用体的内存大小
- 3、枚举的大小
1、结构体内存对齐
结构体内存对齐在笔试和面试中经常被问到,所以做个总结
通过代码验证不同结构体的内存大小:
#include <stdio.h> struct node1{ char c1; int val1; char c2; }; struct node2{ char c1; char c2; int val1; }; struct node3{ char c1; char array[10]; }; struct node4{ char val1; int arrar[10]; }; int main(){ printf("node1 size = %dn",sizeof(struct node1)); printf("node2 size = %dn",sizeof(struct node2)); printf("node3 size = %dn",sizeof(struct node3)); printf("node4 size = %dn",sizeof(struct node4)); return 0; }
代码运行结果为:
通过上述代码运行结果可以发现node1
和node2
定义了相同个数的变量,但是node1的大小为12,node2的大小为8,这是为什么呢?
这里首先明确两个概念:对齐数和最大对齐数,在结构体中对齐数就是每个成员类型的大小,如node1中,对齐数为{1,4,1},在数组中,对齐数不是数组的大小,而是数组成员的大小,所以node3的对齐数为{1,1},node4的对齐数为{1,4}。最大对齐数是对齐数中的最大值(gcc编译器),最大对齐数可能受编译器的影响,通常编译器会有编译器对齐数,最大对齐数应该是编译器对齐数和结构体最大对齐数中较小值,如vs编译器对齐数为8,如果结构体的最大对齐数为16,那么计算结构体的最大对齐数应该为8。我的编译器为gcc,所以最大对齐数为结构体对齐数中的最大值。
知道最大对齐数后,就可以计算结构体的大小了,需要明确结构体的大小一定是最大对齐数的整数倍。那么node1和node2的成员类型是一样的,为什么node1的大小为12字节,node2的大小为8字节呢。这是因为结构体内存的连续性,在存储容量没有到最大对齐数的内存大小时,只要能够保存这个成员,结构体就会将该成员变量保存在一个最大对齐树的内存空间内。这样就避免了内存的过度浪费。
所以,上述各结构体的内存大小计算方式如下:
- sizeof(node1)= 1 + 3(浪费)+ 4 + 1 + 3(浪费) = 12
- sizeof(node2)= 1 + 1 + 2(浪费)+ 4 = 8
- sizeof(node3) = 1 + 1 * 10 = 11
- sizeof(node4) = 1 + 3(浪费)+ 4 * 10 = 44
那么结构体嵌套结构体的大小应该怎么计算呢?举以下例子:
#include <stdio.h> struct node1{ char c1; int val1; char c2; }; struct node2{ char c1; struct node1 node; double val1; }; int main(){ printf("node1 size = %dn",sizeof(struct node1)); printf("node2 size = %dn",sizeof(struct node2)); return 0; }
代码运行的结果为:
可以明确,嵌套结构体的对齐数为所嵌套结构体的最大对齐数,所以node1的对齐数为{1,4,1},node2的对齐数为{1,4,8},最大对齐数分别为4和8,则代码里两个结构体的大小计算方式为:
- sizeof(node1)= 1 + 3(浪费)+ 4 + 1 + 3(浪费) = 12
- sizeof(node2)= 1 + 7(浪费)+ 12 + 4(浪费)+ 8 = 24
2、共用体的内存大小
对于以下共用体,读取它大小的代码如下:
#include <stdio.h> union un1{ int val; char c; double d; }; union un2{ int val; char array[5]; }; int main(){ printf("un1 size = %dn",sizeof(union un1)); printf("un2 size = %dn",sizeof(union un2)); return 0; }
代码运行结果为:
共用体之所以叫共用体,就是因为它的成员变量共享内存,既然共享内存,那么共用体占用的内存空间一定要可以保存内存最大的成员类型,而un1的最大内存成员为double型,大小为8字节,所以un1的大小为8字节,那么un2的内存大小为什么不是5呢?这是因为要内存对齐,共用体也遵循内存对齐原则,un2的最大对齐数是4,因此un2的大小应该是4的整数倍数,所以,sizeof(un2)= 8.
3、枚举的大小
这里顺带提一下枚举的内存大小,代码验证如下:
#include <stdio.h> enum colour { red, green, blue }; enum programlanguage { python = 0xffffffffff, c = 8, java }; int main() { printf("colour size = %dn",sizeof(enum colour)); printf("programlanguage size = %dn",sizeof(enum programlanguage)); return 0; }
代码运行结果为:
可见枚举类型的大小是编译器根据定义的值自行给定的,实际使用中很少会超出4字节大小。
到此这篇关于c++结构体字节对齐和共用体大小的文章就介绍到这了,更多相关结构体字节对齐和共用体大小内容请搜索<计算机技术网(www.ctvol.com)!!>以前的文章或继续浏览下面的相关文章希望大家以后多多支持<计算机技术网(www.ctvol.com)!!>!
需要了解更多c/c++开发分享C++结构体字节对齐和共用体大小,都可以关注C/C++技术分享栏目—计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/936098.html