计算结构体的大小

计算结构体的大小

我们实际生活中,保存的数据一般不会是同一种类型,所以引入了结构体。而结构体的大小也不是成员类型大小的简单相加。需要考虑到系统在存储结构体变量时的地址对齐问题。

由于存储变量地址对齐的问题,结构体大小计算必须满足两条原则:

一、结构体成员的偏移量必须是成员大小的整数倍(0被认为是任何数的整数倍)

二、结构体大小必须是所有成员大小的整数倍

下面来具体分析

1、简单结构体

struct s1{
char ch1;

char ch2;

int i;

};

这个结构体的大小容易计算,满足两个原则即可,为8,那么下面这个呢

struct s2{
char ch1;

int i;

char ch2;

};

这个结构体大小是12,为什么呢?仔细看看两个原则,要满足偏移量是成员的整数倍,ch1偏移量是0,i的偏移量不可能是1,因为1不是i大小4的倍数,所以i的偏移量是4,ch2的偏移量就变为了8,所以满足结构体大小是成员大小整数倍,就是12。

2、成员包含数组的结构体

struct s3{
char ch;

int i;

char str[10];

};

这个结构体的大小是20,先看前两个成员,大小是8,毋庸置疑,这个char类型的数组,只需要把它看做十个char连在一起即可,加起来就是18,再满足结构体大小为成员整数倍,所以大小就是20。

3、成员包含结构体的结构体

struct s4{
char ch;

int i;

struct s{
char ch1;

int j;

};

float f;

};

里面这个结构体的大小是8,那么是否结构体大小就要向8对齐呢?这个结构体的大小是20,很明显不是8的倍数。所以计算结构体大小时是把里面这个结构体就看做是一个char,和一个int,不是看做一个整体。

4、成员包含联合体的结构体

struct s5{
char ch;

int i;

union{
char ch1;

int j;

};

};

联合体大小就是成员中最大类型的大小,所以这个结构体大小是12.

5、指定对齐值

(1)对齐值小于最大类型成员值

#pragma pack(4) //指定向4对齐 最大是8

struct s6{
char ch;

int i;

float f;

double d;

};

如果我们没有指定对齐值,这个结构体大小是24,我们指定向4对齐,所以大小是4的倍数,所以结构体大小是20。

(2)对齐值大于最大类型成员值

#pragma pack(10)

struct s7{
char ch;

int i;

float f;

double d;

};

我们指定的对齐值是10,最大为8,是否就向10对齐?不是,当指定对齐值大于自身对齐值时,向自身对其值对齐,大小是24.

总的来说,向指定对齐值和自身对齐值中较小的那个值对齐。
————————————————
版权声明:本文为优快云博主「陈立臣」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.youkuaiyun.com/chenlichenforlinux21/article/details/103311310

计算结构体大小时,需要考虑到内存对齐的问题。内存对齐是为了优化内存访问速度而进行的一种技术,它要求不同数据类型的变量在内存中的存储地址要按照一定规则进行对齐。具体来说,每个数据类型都有一个对齐值,即该数据类型变量在内存中存储的起始地址必须是该对齐值的倍数。 在C语言中,可以使用`sizeof`运算符来计算结构体大小,但是这个大小可能会受到内存对齐的影响。为了确保计算出的大小是考虑了内存对齐的,我们可以使用`__alignof__`关键字来获取每个成员变量的对齐值,并手动进行对齐计算。 下面是一个示例代码,演示如何使用内存对齐计算结构体大小: ```c #include <stdio.h> struct my_struct { char c; int i; double d; }; int main() { struct my_struct s; size_t size = sizeof(s); size_t align_c = __alignof__(s.c); size_t align_i = __alignof__(s.i); size_t align_d = __alignof__(s.d); size_t align = align_c > align_i ? align_c : align_i; align = align > align_d ? align : align_d; size_t padding_c = align - sizeof(s.c) % align; size_t padding_i = align - sizeof(s.i) % align; size_t padding_d = align - sizeof(s.d) % align; size_t padding = padding_c + padding_i + padding_d; size += padding; printf("Size of my_struct: %zu\n", size); return 0; } ``` 在上面的示例代码中,我们首先定义了一个`my_struct`结构体,其中包含一个`char`类型的成员变量`c`、一个`int`类型的成员变量`i`和一个`double`类型的成员变量`d`。然后我们使用`sizeof`运算符计算结构体大小,并使用`__alignof__`关键字获取每个成员变量的对齐值。接下来,我们计算结构体需要进行的对齐和填充,最后将填充的大小加入到结构体大小中,输出计算出的结构体大小。 需要注意的是,对齐值可能会因为编译器和操作系统的不同而有所差异,因此在实际应用中需要谨慎处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值