结构体大小问题

     先看一例:

 1 #include <stdio.h>
  2 #include <string.h>
  3 
  4 struct sss{
  5     //int c;
  6     long long s;
  7     char k;
  8 };  
  9 
 10 struct aaa{
 11     char a;
 12     struct sss b;
 13     int s;
 14     char k;
 15 };
 16 
 17 int main()
 18 {   
 19     printf("%d\n", sizeof(struct sss));
 20     printf("%d\n", sizeof(struct aaa));
 21     
 22     return 0;
 23 }

结果是12,24.

结构体sss中,s占8个,下面满足>4,则以实际来算,不足4个,以4个来算.

结构体aaa中,与之似.a占4个,b占12个,s占4个,k占4个.总共24个.

### 结构体大小计算方法 在C/C++中,结构体大小不仅仅取决于其成员变量的实际占用字节数,还需要考虑内存对齐规则的影响。以下是详细的计算方法: #### 1. **基本概念** - **字节对齐**:为了提高CPU访问内存的速度,编译器会对数据类型的存储地址进行调整,使其满足一定的对齐要求。 - **对齐单位**:通常情况下,数据类型的对齐单位等于该类型本身的大小(如`int`为4字节,则对齐单位为4)。但在某些特殊场景下,可以通过编译选项或属性改变这一行为。 --- #### 2. **结构体内存布局原则** ##### (1) 成员变量的对齐规则 对于结构体中的每一个成员变量: - 起始地址必须是对齐单位的整数倍[^2]。 - 对齐单位取当前成员变量的数据类型大小和全局默认对齐值之间的最小值[^3]。 例如,在大多数平台上,默认对齐值为8字节。如果某个成员是一个`char`型变量(大小为1字节),则它的实际对齐单位仍为1字节;如果是`double`型变量(大小为8字节),则对齐单位为8字节。 ##### (2) 整体结构体的对齐规则 - 结构体的整体大小必须是最大成员对齐单位的整数倍[^3]。 - 如果最终计算得到的结构体大小不符合此条件,则会在末尾填充额外的空间以达到对齐要求。 --- #### 3. **具体例子分析** 以下通过几个实例来说明结构体大小的计算过程。 ##### 示例 1 ```c struct S1 { char c1; // 1 byte, 默认对齐数为1 int i; // 4 bytes, 默认对齐数为4 }; ``` - `c1`位于偏移量0的位置; - `i`需要放置在其对齐单位(4字节)的整数倍位置上,因此从第4字节开始存放; - 总共占据5字节,但由于整体结构体需按最大成员对齐单位(4字节)补齐,故最终大小为8字节。 结果:`sizeof(S1)` = 8 字节。 --- ##### 示例 2 ```c struct S2 { char c1; short s; int i; } __attribute__((packed)); ``` - 使用了`__attribute__((packed))`关键字,关闭了字节对齐功能; - 各成员依次紧密排列,无任何填充。 结果:`sizeof(S2)` = 7 字节[^1]。 --- ##### 示例 3 ```c struct S3 { double d; // 8 bytes, 默认对齐数为8 char c; // 1 byte, 默认对齐数为1 }; ``` - `d`占用了前8字节; - `c`紧随其后,由于无需额外对齐,直接放在第9字节; - 最终还需补足至最大成员对齐单位(8字节)的整数倍,因此增加7字节填充。 结果:`sizeof(S3)` = 16 字节[^2]。 --- #### 4. **查询特定结构体大小** 可以直接使用`sizeof()`运算符获取指定结构体大小。例如: ```cpp #include <iostream> using namespace std; struct Example { char a; int b; }; int main() { cout << "Size of Example: " << sizeof(Example) << " bytes" << endl; } ``` 注意:不同平台上的默认对齐设置可能有所不同,可能导致同一段代码在不同的环境中返回不同的结果。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值