乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

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

       方海龍的書(shū)館 2014-09-25

      1、前言

        

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

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

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

      struct buffer
      {
          int data_len;   //長(zhǎng)度
          char data[0];  //起始地址
      };

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

        

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

       

      復(fù)制代碼
       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 }
      復(fù)制代碼

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

      3、實(shí)際當(dāng)中的用法

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

      復(fù)制代碼
       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 }
      復(fù)制代碼

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

       

      參考資料:

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

       

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

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶(hù) 評(píng)論公約

        類(lèi)似文章 更多