這種特性用來射你那個結構體中最後一個成員是特殊成員,它是不存在的
它包含如下規則:
1、必須是最後一個數組成員
2、結構體中至少有一個其他成員
3、使用[]進行定義
/*************************************************************************
> File Name: dongtai.c
> Author: gaopeng
> 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);
fwrite(d3,1,LEN(3),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
如果要分析 實際上 ,主要取決于這裡
char gs[]; //flexible array number
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起來友善,寫檔案也友善
如果
char *gs; //a char pointer
這種方式就不連續的,比較麻煩。