结构体零长度数组的意义(深入)1
需积分: 0 121 浏览量
更新于2022-08-08
收藏 18KB DOCX 举报
结构体零长度数组的意义(深入)
在 Linux 系统中,结构体最后的长度为 0 或者 1 的数组是一个非常重要的概念。这在 /usr/include/linux/if_pppox.h 里面有一个结构体的定义,名为 struct pppoe_tag:
```c
struct pppoe_tag {
__u16 tag_type;
__u16 tag_len;
char tag_data[0];
} __attribute__((packed));
```
这个结构体的最后一个成员是可变长的数组,对于 TLV(Type-Length-Value)形式的结构,或者其他需要变长度的结构体,用这种方式定义最好。
使用这种方式定义结构体的好处是非常明显的。创建时,可以使用 malloc 动态分配空间,例如:
```c
struct pppoe_tag *sample_tag;
__u16 sample_tag_len = 10;
sample_tag = (struct pppoe_tag *)malloc(sizeof(struct pppoe_tag) + sizeof(char) * sample_tag_len);
```
这样,我们可以在结构体中添加可变长的数据,并且可以使用数组的方式访问这些数据。释放时,直接使用 free 函数将整个结构体释放掉就可以了。
但是,这种方式和使用 char *tag_data 有很大的区别。为了说明这个问题,我们可以使用以下的程序:
```c
struct tag1 {
int a;
int b;
} __attribute__((packed));
struct tag2 {
int a;
int b;
char *c;
} __attribute__((packed));
struct tag3 {
int a;
int b;
char c[0];
} __attribute__((packed));
struct tag4 {
int a;
int b;
char c[1];
} __attribute__((packed));
int main() {
struct tag2 l_tag2;
struct tag3 l_tag3;
struct tag4 l_tag4;
memset(&l_tag2, 0, sizeof(struct tag2));
memset(&l_tag3, 0, sizeof(struct tag3));
memset(&l_tag4, 0, sizeof(struct tag4));
printf("size of tag1 = %d\n", sizeof(struct tag1));
printf("size of tag2 = %d\n", sizeof(struct tag2));
printf("size of tag3 = %d\n", sizeof(struct tag3));
printf("l_tag2 = %p, &l_tag2.c = %p, l_tag2.c = %p\n", &l_tag2, &l_tag2.c, l_tag2.c);
printf("l_tag3 = %p, l_tag3.c = %p\n", &l_tag3, l_tag3.c);
printf("l_tag4 = %p, l_tag4.c = %p\n", &l_tag4, l_tag4.c);
exit(0);
}
```
这个程序的运行结果如下:
```
size of tag1 = 8
size of tag2 = 12
size of tag3 = 8
l_tag2 = 0xbffffad0, &l_tag2.c = 0xbffffad8, l_tag2.c = (nil)
l_tag3 = 0xbffffac8, l_tag3.c = 0xbffffad0
l_tag4 = 0xbffffabc, l_tag4.c = 0xbffffac4
```
从上面的程序和运行结果可以看出,tag2 和 tag3 的 sizeof 结果不同,tag2 的 sizeof 结果是 12,而 tag3 的 sizeof 结果是 8。这是因为 tag2 中的 char *c 是一个指针,而 tag3 中的 char c[0] 是一个可变长的数组。tag4 中的 char c[1] 是一个长度固定为 1 的数组。
因此,在定义结构体时,需要根据实际情况选择使用 char *tag_data 或者 char tag_data[0],以达到预期的效果。
小明斗
- 粉丝: 41
- 资源: 329
最新资源
- 几何物体检测43-YOLO(v5至v9)、COCO、CreateML、Paligemma、TFRecord、VOC数据集合集.rar
- 基于cruise的燃料电池功率跟随仿真,按照丰田氢能源车型搭建,在wltc工况下跟随效果好,最高车速175,最大爬坡30,百公里9s均已实现 1.模型通过cruise simulink联合仿真,策略
- C#源码 上位机 联合Visionpro 通用框架开发源码,已应用于多个项目,整套设备程序,可以根据需求编出来,具体Vpp功能自己编 程序包含功能 1.自动设置界面窗体个数及分布 2.照方式以命令触
- 程序名称:悬架设计计算程序 开发平台:基于matlab平台 计算内容:悬架偏频刚度挠度;螺旋弹簧,多片簧,少片簧,稳定杆,减震器的匹配计算;悬架垂向纵向侧向力学、纵倾、侧倾校核等;独立悬架杠杆比,等效
- 华为OD+真题及解析+智能驾驶
- jQuery信息提示插件
- 基于stm32的通信系统,sim800c与服务器通信,无线通信监测,远程定位,服务器通信系统,gps,sim800c,心率,温度,stm32 由STM32F103ZET6单片机核心板电路、DS18B2
- 充电器检测9-YOLO(v5至v11)、COCO、Create充电器检测9L、Paligemma、TFRecord、VOC数据集合集.rar
- 华为OD+考试真题+实现过程
- 保险箱检测51-YOLO(v5至v11)、COCO、CreateML、Paligemma、TFRecord、VOC数据集合集.rar