我的sizeof(struct)探索之旅

本文通过一道面试题探讨了结构体在不同编译器中如何进行内存对齐,解释了为何同样结构体在不同对齐设置下大小不同,并通过实例展示了嵌套结构体的情况。


今天接到一个电话面试,被问到这个问题,很自信的回答却被嘲讽了,naive,还是自己没有掌握透彻,今天就好好八一八这玩意儿。

面试问我的是这样的一个结构体的大小(sizeof)

struct A{
    char c;
    double d;
    int a;
};
我回答4+8+4=16,结果面试官让我自己敲一敲试一试。
自己VS2013试了一下还真是错的,是24

百度了下,这篇博文(点击打开链接)讲得挺清楚,自己看了看,总结一下:

1、如果编译器不指定自定义的对齐方式的话,编译器按照默认的方式对齐

默认的方式是指什么呢?vc和vs里面是按照8字节对齐,g++里面是按照4字节对齐

具体点说,默认的对齐方式指当前要存储的这个成员变量的大小要能整除当前的偏移量(相对于结构变量首地址的)。

最后,所有的字节数相加要是成员变量里面最大的那个变量的大小的倍数(比如有一个8字节的变量,对齐之后总共占20个字节,那么需要补4个够8的倍数到24)

注意C++里面最大的默认数据类型的大小为8(int 4,long4,long long 8, float 4, double 8)

2、如果指定了n字节对齐的方式,比如4字节对齐。那么如果n大于下一个要存的成员变量的大小,按n对齐,否则按成员变量的大小对齐(或者说是默认的方式对齐)

最后,所有的字节数相加要是n的倍数(vs默认的为8)


所以,回顾我自己的那一道面试题,我计算的时候是按照4字节对齐算的,8字节对齐的时候结果不一样。


同时,我自己思考了一下,如果一个结构体的成员变量是另一个结构体会怎么样呢?

做了个实验:


感觉就像是将AA里面的成员变量直接贴在那个位置之后算出来的结果

说明,并不是按照AA(最大的成员变量)的大小来对齐(16*2),而是按照基本类型对齐

在C语言和C#中,`sizeof`操作符在结构体上有不同的使用方式和原理。 ### C语言中`sizeof`对结构体的使用及原理 在C语言里,`sizeof`是一种单目操作符,以字节形式给出其操作数的存储大小,操作数可以是表达式或括在括号内的类型名,其返回值是`size_t`,在64位机器下被定义为`long unsigned int` [^1]。 当操作数为结构体时,`sizeof`会计算该结构体在内存中所占的字节数。计算时会考虑结构体成员的排列以及内存对齐的影响。例如,下面的代码展示了`sizeof`对结构体的使用: ```c #include <stdio.h> struct Example { int a; char b; double c; }; int main() { struct Example ex; size_t size = sizeof(struct Example); printf("结构体Example的大小是: %zu 字节\n", size); return 0; } ``` 在这个例子中,`sizeof(struct Example)`会计算`Example`结构体的大小。由于内存对齐的存在,该结构体的实际大小可能大于各个成员大小的简单相加。 ### C#中`sizeof`对结构体的使用及原理 在C#中,使用操作符`sizeof`可以检查结构体数据类型所占的内存。不过需要注意的是,必须在不安全的代码环境下才能使用`sizeof`来检查自定义结构体所占的内存 [^2]。 以下是一个示例代码: ```csharp using System; class Program { static void Main(string[] args) { unsafe { int x = sizeof(Student); Console.WriteLine(x); } } } struct Student { int ID; long Score; } ``` 在上述代码中,通过`sizeof(Student)`计算`Student`结构体所占的内存大小,并将结果存储在变量`x`中,最后将其输出。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值