设为首页 加入收藏

TOP

C语言变长数组data[0](一)
2015-01-22 21:34:01 来源: 作者: 【 】 浏览:115
Tags:语言 data
1、前言
?
  
?
  今天在看代码中遇到一个结构中包含char data[0],第一次见到时感觉很奇怪,数组的长度怎么可以为零呢?于是上网搜索一下这样的用法的目的,发现在linux内核中,结构体中经常用到data[0]。这样设计的目的是让数组长度是可变的,根据需要进行分配。方便操作,节省空间。
?
2、data[0]结构
?
经常遇到的结构形状如下:
?
struct buffer
{
? ? int data_len; ? //长度
? ? char data[0]; ?//起始地址
};
? 在这个结构中,data是一个数组名;但该数组没有元素;该数组的真实地址紧随结构体buffer之后,而这个地址就是结构体后面数据的地址(如果给这个结构体分配的内容大于这个结构体实际大小,后面多余的部分就是这个data的内容);这种声明方法可以巧妙的实现C语言里的数组扩展。
?
  
?
  写个程序对比char data[0],char *data, char data[],如下所示:
?
 
?
复制代码
?1 #include
?2 #include
?3 #include
?4 #include
?5?
?6 typedef struct
?7 {
?8 ? ? int data_len;
?9 ? ? char data[0];
10 }buff_st_1;
11?
12 typedef struct
13 {
14 ? ? int data_len;
15 ? ? char *data;
16 }buff_st_2;
17?
18 typedef struct?
19 {
20 ? ? int data_len;
21 ? ? char data[];
22 }buff_st_3;
23?
24 int main()
25 {
26 ? ? printf("sizeof(buff_st_1)=%u\n", sizeof(buff_st_1));
27 ? ? printf("sizeof(buff_st_2)=%u\n", sizeof(buff_st_2));
28 ? ? printf("sizeof(buff_st_3)=%u\n", sizeof(buff_st_3));
29?
30 ? ? buff_st_1 buff1;
31 ? ? buff_st_2 buff2;
32 ? ? buff_st_3 buff3;
33?
34 ? ? printf("buff1 address:%p,buff1.data_len address:%p,buff1.data address:%p\n",
35 ? ? ? ? &buff1, &(buff1.data_len), buff1.data);
36?
37 ? ? printf("buff2 address:%p,buff2.data_len address:%p,buff2.data address:%p\n",
38 ? ? ? ? &buff2, &(buff2.data_len), buff2.data);
39?
40 ? ? printf("buff3 address:%p,buff3.data_len address:%p,buff3.data address:%p\n",
41 ? ? ? ? &buff3, &(buff3.data_len), buff3.data);
42?
43 ? ? return 0;
44 }
复制代码
?
?
从结果可以看出data[0]和data[]不占用空间,且地址紧跟在结构后面,而char *data作为指针,占用4个字节,地址不在结构之后。
?
3、实际当中的用法
?
? ? ?在实际程序中,数据的长度很多是未知的,这样通过变长的数组可以方便的节省空间。对指针操作,方便数据类型的转换。测试程序如下:
?
复制代码
?1 #include
?2 #include
?3 #include
?4 #include
?5?
?6 typedef struct
?7 {
?8 ? ? int data_len;
?9 ? ? char data[0];
10 }buff_st_1;
11?
12 typedef struct
13 {
14 ? ? int data_len;
15 ? ? char *data;
16 }buff_st_2;
17?
18 typedef struct?
19 {
20 ? ? int data_len;
21 ? ? char data[];
22 }buff_st_3;
23?
24 typedef struct?
25 {
26 ? ? uint32_t id;
27 ? ? uint32_t age;
28 }student_st;
29?
30?
31 void print_stu(const student_st *stu)
32 {
33 ? ? printf("id:%u,age:%u\n", stu->id, stu->age);
34 }
35?
36 int main()
37 {
38 ? ? student_st *stu = (student_st *)malloc(sizeof(student_st));
39 ? ? stu->id = 100;
40 ? ? stu->age = 23;
41?
42 ? ? student_st *tmp = NULL;
43?
44 ? ? buff_st_1 *buff1 = (buff_st_1 *)malloc(sizeof(buff_st_1) + sizeof(student_st));
45 ? ? buff1->data_len = sizeof(student_st);
46 ? ? memcpy(buff1->data, stu, buff1->data_len);
47 ? ? printf("buff1 address:%p,buff1->data_len address:%p,buff1->data address:%p\n",
48 ? ? ? ? buff1, &(buff1->data_len), buff1->data);
49?
50 ? ? tmp = (student_st*)buff1->data;
51 ? ? print_stu(tmp);
52?
53 ? ? buff_st_2 *buff2 = (buff_st_2 *)malloc(sizeof(buff_st_2));
54 ? ? buff2->data_len = sizeof(student_st);
55 ? ? buff2->data = (char *)malloc(buff2->data_len);
56 ? ? memcpy(buff2->data, stu, buff2->data_len);
57 ? ? printf("buff2 address:%p,buff2->data_len address:%p,buff2->data address:%p\n",
58 ? ? ? ? buff2, &(buff2->d
首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇让你提前认识软件开发(23):如何.. 下一篇c语言中指针悬空

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: