日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

C語言變長數(shù)組data[0]【總結(jié)】

 方海龍的書館 2014-09-25

1、前言

  

  今天在看代碼中遇到一個結(jié)構(gòu)中包含char data[0],第一次見到時感覺很奇怪,數(shù)組的長度怎么可以為零呢?于是上網(wǎng)搜索一下這樣的用法的目的,發(fā)現(xiàn)在linux內(nèi)核中,結(jié)構(gòu)體中經(jīng)常用到data[0]。這樣設計的目的是讓數(shù)組長度是可變的,根據(jù)需要進行分配。方便操作,節(jié)省空間。

2、data[0]結(jié)構(gòu)

經(jīng)常遇到的結(jié)構(gòu)形狀如下:

struct buffer
{
    int data_len;   //長度
    char data[0];  //起始地址
};

  在這個結(jié)構(gòu)中,data是一個數(shù)組名;但該數(shù)組沒有元素;該數(shù)組的真實地址緊隨結(jié)構(gòu)體buffer之后,而這個地址就是結(jié)構(gòu)體后面數(shù)據(jù)的地址(如果給這個結(jié)構(gòu)體分配的內(nèi)容大于這個結(jié)構(gòu)體實際大小,后面多余的部分就是這個data的內(nèi)容);這種聲明方法可以巧妙的實現(xiàn)C語言里的數(shù)組擴展。

  

  寫個程序?qū)Ρ萩har data[0],char *data, char data[],如下所示:

 

復制代碼
 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <string.h>
 4 #include <stdint.h>
 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 }
復制代碼

從結(jié)果可以看出data[0]和data[]不占用空間,且地址緊跟在結(jié)構(gòu)后面,而char *data作為指針,占用4個字節(jié),地址不在結(jié)構(gòu)之后。

3、實際當中的用法

     在實際程序中,數(shù)據(jù)的長度很多是未知的,這樣通過變長的數(shù)組可以方便的節(jié)省空間。對指針操作,方便數(shù)據(jù)類型的轉(zhuǎn)換。測試程序如下:

復制代碼
 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #include <string.h>
 4 #include <stdint.h>
 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->data_len), buff2->data);
59 
60     tmp = (student_st *)buff2->data;
61     print_stu(tmp);
62 
63     buff_st_3 *buff3 = (buff_st_3 *)malloc(sizeof(buff_st_3) + sizeof(student_st));
64     buff3->data_len = sizeof(student_st);
65     memcpy(buff3->data, stu, buff3->data_len);
66     printf("buff3 address:%p,buff3->data_len address:%p,buff3->data address:%p\n",
67         buff3, &(buff3->data_len), buff3->data);
68 
69     tmp = (student_st*)buff1->data;
70     print_stu(tmp);
71 
72     free(buff1);
73 
74     free(buff2->data);
75     free(buff2);
76 
77     free(buff3);
78     free(stu);
79     return 0;
80 }
復制代碼

程序執(zhí)行結(jié)果如下:
  采用char *data,需要進行二次分配,操作比較麻煩,很容易造成內(nèi)存泄漏。而直接采用變長的數(shù)組,只需要分配一次,然后進行取值即可以。

 

參考資料:

http://blog.csdn.net/maopig/article/details/7243646

 

    本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多