C99 flexible array number 伸縮型陣列成員

gaopengtttt發表於2016-06-05
這種特性用來射你那個結構體中最後一個成員是特殊成員,它是不存在的
它包含如下規則:
1、必須是最後一個陣列成員
2、結構體中至少有一個其他成員
3、使用[]進行定義



/*************************************************************************
  > File Name: dongtai.c
  > Author: gaopeng
  > Mail:
  > Created Time: Wed 25 May 2016 03:46:20 AM CST
 ************************************************************************/

#include<stdio.h>
#include <stdlib.h>
#include <string.h>

#define LEN(a)  strlen(argv[a]) + sizeof(NFDATA) + 1

typedef struct nofixed
{
        int leng_t;
        char gs[];
} NFDATA;


int readpa(const int *ar,const int hmud)
{
        if(*ar == hmud)
        {
                return 1;
        }
        else
        {
                return 0;
        }

}

 

int main (int argc,char *argv[])
{
        FILE *fd;
        NFDATA *d1;
        NFDATA *d2;
        NFDATA *d3;

        if( readpa(&argc,5 ) != 1  )
        {
                printf("5 argc must\n");
                exit(1);
        }

        d1 = (NFDATA *)malloc(LEN(1));
        d1->leng_t = strlen(argv[1]);
        d1->gs[d1->leng_t] = '\0';
        memcpy(d1->gs , argv[1] , d1->leng_t);

        d2 = (NFDATA *)malloc( LEN(2));
        d2->leng_t = strlen(argv[2]);
        d2->gs[d2->leng_t] = '\0';
        memcpy(d2->gs , argv[2] , d1->leng_t);

        d3 = (NFDATA *)malloc( LEN(3));
        d3->leng_t = strlen(argv[3]);
        d3->gs[d3->leng_t] = '\0';
        memcpy(d3->gs , argv[3] , d3->leng_t);

        printf("argv1 %ld,%ld,%p,%p,%s,%d\n", sizeof(*d1),strlen(d1->gs),d1, d1->gs,d1->gs,d1->leng_t);
        printf("argv2 %ld,%ld,%p,%p,%s,%d\n", sizeof(*d2),strlen(d2->gs),d2, d2->gs,d2->gs,d2->leng_t);
        printf("argv3 %ld,%ld,%p,%p,%s,%d\n", sizeof(*d3),strlen(d3->gs),d3, d3->gs,d3->gs,d3->leng_t);
   
        if((fd = fopen(argv[4],"w")) == NULL)
        {
                printf("open file error!\n");
                exit(11);
        }

        fwrite(d1,1,LEN(1),fd);
        printf("file pointer: %ld\n",ftell(fd));
        fwrite(d2,1,LEN(2),fd);
        printf("file pointer: %ld\n",ftell(fd));
        fwrite(d3,1,LEN(3),fd);
        printf("file pointer: %ld\n",ftell(fd));

        free(d1);
        free(d2);
        free(d3);

        fclose(fd);

}

執行程式
./a.out  gao1 gao2 gao3 save3.dmp
這段程式碼就使用了這種特性將命令列引數這個不定的字元素組儲存到了檔案中,而且檔案中沒有浪費的空間
當然這樣的做法也要記憶體中沒有浪費的空間。不過相容性可能有一些問題。
使用
 hexdump -Cv save3.dmp
檢視二進位制檔案
00000000  04 00 00 00 67 61 6f 31  00 04 00 00 00 67 61 6f  |....gao1.....gao|
00000010  32 00 04 00 00 00 67 61  6f 33 00                        |2.....gao3.|
0000001b


如果要分析 實際上 ,主要取決於這裡

#define LEN(a)  strlen(argv[a]) + sizeof(NFDATA) + 1

typedef struct nofixed
{
        int leng_t;
        char gs[];  //flexible array number
} NFDATA;

 d1 = (NFDATA *)malloc(LEN(1));
 d1->leng_t = strlen(argv[1]);
 d1->gs[d1->leng_t] = '\0'; 
 memcpy(d1->gs , argv[1] , d1->leng_t);

本來整個struct只需要4BYTES的空間,但是我們分配空間的時候加上了strlen(argv[a])+1
意思就是擴張一個引數長度+1出來,這裡的+1就是儲存'\0'結束符而已。
最後複製argv[1]的字元到d1->gs中

認為這種方式最好的地方在於記憶體中分配的空間的連續的 free起來方便,寫檔案也方便

如果
typedef struct nofixed
{
        int leng_t;
        char *gs; //a char pointer  
} NFDATA;
這種方式就不連續的,比較麻煩。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/7728585/viewspace-2114485/,如需轉載,請註明出處,否則將追究法律責任。

相關文章