C/C++ 中的0長數組(柔性數組)

在標準CC++0長數組如charArray[0]是不容許使用的,由於這從語義邏輯上看,是徹底沒有意義的。數組

可是,GUN中卻容許使用,並且,不少時候,應用在了變長結構體中,如:網絡

StructPacketsocket

{spa

Int state;.net

Int len;指針

Char cData[0]; //這裏的0長結構體就爲變長結構體提供了很是好的支持blog

};內存

 

首先對0長數組作一個解釋:編譯器

用途 :長度爲0的數組的主要用途是爲了知足須要變長度的結構體。編譯

用法 :在一個結構體的最後 ,申明一個長度爲0的數組,就可使得這個結構體是可變長的。對於編譯器來講,此時長度爲0的數組並不佔用空間,由於數組名自己不佔空間,它只是一個偏移量, 數組名這個符號自己代 表了一個不可修改的地址常量 (注意:數組名永遠都不會是指針! ),但對於這個數組的大小,咱們能夠進行動態分配

 

請仔細理解後半部分,對於編譯器而言,數組名僅僅是一個符號,它不會佔用任何空間,它在結構體中,只是表明了一個偏移量,表明一個不可修改的地址常量!

 

對於0長數組的這個特色,很容易構造出變成結構體,如緩衝區,數據包等等:

Struct Buffer

{

Int len;

Char cData[0];

};

這樣的變長數組經常使用於網絡通訊中構造不定長數據包,不會浪費空間浪費網絡流量,好比我要發送1024字節的數據,若是用定長包,假設定長包的長度爲2048,就會浪費1024個字節的空間,也會形成沒必要要的流量浪費

Struct packet

{

    char data[2048];

}

packet p;

memcpy(p.data,"1024 datas.........",1024)

send(socket,(char*)&p,sizeof(p));

因爲考慮到數據的溢出,變長數據包中的data數組長度通常會設置得足夠長足以容納最大的數據,所以packet中的data數組不少狀況下都沒有填滿數據,所以形成了浪費,而若是咱們用變長數組來進行封包的話,就不會形成浪費(最多會形成4個字節的浪費,包頭的int型的len不屬於數據所以算是浪費),如前面的Buffer結構體,假如咱們要發送1024個字節,咱們如何構造這個數據包呢:

char *tmp = (char*)malloc(sizeof(Buffer)+1024) //這句代碼的做用是申請一塊連續的內存空間,這塊內存空間的長度是Buffer的大小加上1024數據的大小,由兩部分構成,sizeof(Buffer)和1024,若是仔細觀察的話,會發現這種申請方法比第一種多了一段sizeof(Buffer)大小的空間,緣由何在?以下

Buffer *p = (Buffer*)tmp;

p->len = 1024;

memcpy(p.cData,"1024 datas............",1024);

如上三行代碼,首先作一個強制類型轉換,Buffer類型的指針指向內存的起始位置,這段內存要分兩部分使用,前部分4個字節p->len,做爲包頭(就是多出來的那部分),這個包頭是用來描述緊接着包頭後面的數據部分的長度,這裏是1024,因此前四個字節賦值爲1024(既然咱們要構造不定長數據包,那麼這個包到底有多長呢,所以,咱們就必須經過一個變量來代表這個數據包的長度,這就是len的做用),而緊接其後的內存是真正的數據部分,經過p->cData定位到該部分的起始地址,最後,進行一個memcpy()內存拷貝,把要發送的數據填入到這段內存當中,最後:

send(socket,p,sizeof(Buffer)+1024);發送數據

轉自:http://blog.csdn.net/yby4769250/article/details/7294696

相關文章
相關標籤/搜索