面试题答案
一键面试- 不同编译器下的内存布局:
- GCC:
- 在默认情况下,GCC遵循结构体成员对齐规则。对于
struct { char a; int b; short c; } myStruct;
,char
类型通常占1字节,int
类型在32位和64位系统下一般占4字节,short
类型占2字节。由于对齐规则,a
占1字节后,为了使b
能按4字节对齐(int
通常按其自身大小对齐),会在a
后填充3字节,b
占4字节,c
占2字节,总共占用1 + 3 + 4 + 2 = 10字节。
- 在默认情况下,GCC遵循结构体成员对齐规则。对于
- Visual Studio:
- Visual Studio同样遵循结构体成员对齐规则。类似地,
a
占1字节,为使b
按4字节对齐,a
后填充3字节,b
占4字节,c
占2字节,总共也是1 + 3 + 4 + 2 = 10字节。不过,Visual Studio有自己的预编译指令(如#pragma pack
)可以改变默认的对齐方式。
- Visual Studio同样遵循结构体成员对齐规则。类似地,
- GCC:
- 成员变量顺序和类型选择影响内存布局的原因:
- 对齐规则:不同类型的变量有不同的对齐要求。这是为了提高CPU访问内存的效率,因为CPU访问内存时通常按特定的字节边界(如2字节、4字节、8字节等)进行读取。例如,
int
类型在很多系统下按4字节对齐,这意味着它的地址应该是4的倍数。如果结构体成员顺序不合理,就会导致填充字节的出现,增加结构体的总体大小。 - 类型大小:不同类型的变量占用不同大小的字节数,如
char
占1字节,int
占4字节,short
占2字节等。不同的类型组合和顺序会直接影响内存布局和结构体总体大小。
- 对齐规则:不同类型的变量有不同的对齐要求。这是为了提高CPU访问内存的效率,因为CPU访问内存时通常按特定的字节边界(如2字节、4字节、8字节等)进行读取。例如,
- 调整成员变量顺序以减少内存占用:
- 为了尽量减少内存占用,应该按照成员变量大小从小到大的顺序排列。对于上述结构体,可以调整为
struct { char a; short c; int b; } myStruct;
。此时,a
占1字节,c
占2字节,c
后无需填充,因为b
的对齐要求为4字节,a
和c
总共占3字节,此时再填充1字节使b
按4字节对齐,b
占4字节,总共占用1 + 2 + 1 + 4 = 8字节,相比于之前的顺序减少了2字节。
- 为了尽量减少内存占用,应该按照成员变量大小从小到大的顺序排列。对于上述结构体,可以调整为