结构体零长度数组的意义(深入)1

preview
需积分: 0 1 下载量 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
上传资源 快速赚钱
voice
center-task 前往需求广场,查看用户热搜