结构体中最后一个成员为[0]或[1]长度数组(柔性数组成员)的用法
結構體中最后一個成員為[0]長度數(shù)組的用法:這是個廣泛使用的常見技巧,常用來構成緩沖區(qū)。比起指針,用空數(shù)組有這樣的優(yōu)勢:(1)、不需要初始化,數(shù)組名直接就是所在的偏移;(2)、不占任何空間,指針需要占用int長度空間,空數(shù)組不占任何空間?!斑@個數(shù)組不占用任何內存”,意味著這樣的結構節(jié)省空間;“該數(shù)組的內存地址就和它后面的元素地址相同”,意味著無需初始化,數(shù)組名就是后面元素的地址,直接就能當指針使用。
這樣的寫法最適合制作動態(tài)buffer,因為可以這樣分配空間malloc(sizeof(structXXX) + buff_len); 直接就把buffer的結構體和緩沖區(qū)一塊分配了。用起來也非常方便,因為現(xiàn)在空數(shù)組其實變成了buff_len長度的數(shù)組了。這樣的好處是:(1)、一次分配解決問題,省了不少麻煩。為了防止內存泄露,如果是分兩次分配(結構體和緩沖區(qū)),那么要是第二次malloc失敗了,必須回滾釋放第一個分配的結構體。這樣帶來了編碼麻煩。其次,分配了第二個緩沖區(qū)以后,如果結構里面用的是指針,還要為這個指針賦值。同樣,在free這個buffer的時候,用指針也要兩次free。如果用空數(shù)組,所有問題一次解決。(2)、小內存的管理是非常困難的,如果用指針,這個buffer的struct部分就是小內存了,在系統(tǒng)內存在多了勢必嚴重影響內存管理的性能。要是用空數(shù)組把struct和實際數(shù)據(jù)緩沖區(qū)一次分配大塊問題,就沒有這個問題。如此看來,用空數(shù)組既簡化編碼,又解決了小內存碎片問題提高了性能。
結構體最后使用0或1長度數(shù)組的原因:主要是為了方便的管理內存緩沖區(qū)(其實就是分配一段連續(xù)的內存,減少內存的碎片化),如果直接使用指針而不使用數(shù)組,那么,在分配內存緩沖區(qū)時,就必須分配結構體一次,然后再分配結構體內的指針一次,(而此時分配的內存已經(jīng)與結構體的內存不連續(xù)了,所有要分別管理即申請和釋放)而如果使用數(shù)組,那么只需要一次就可以全部分配出來,反過來,釋放時也是一樣,使用數(shù)組,一次釋放。使用指針,得先釋放結構體內的指針,再釋放結構體,還不能顛倒順序。
結構體中最后一個成員為[1]長度數(shù)組的用法:與長度為[0]數(shù)組的用法相同,改寫為[1]是出于可移植性的考慮。有些編譯器不支持[0]數(shù)組,可將其改成[]或[1].
???????? 不完整類型(incomplete type):它缺乏足夠的信息例如長度去描述一個完整的對象。(1)、前向聲明就是一種常用的不完整類型, class base; struct test; base和test只給出了聲明,沒有給出定義。不完整類型必須通過某種方式補充完整,才能使用它們進行實例化,否則只能用于定義指針或引用,否則只能用于指針或引用,因為此時實例化的是指針或引用本身,不是base或test對象。(2)、一個未知長度的數(shù)組也屬于不完整類型:extern int a[]; extern不能去掉,因為數(shù)組的長度未知,不能作為定義出現(xiàn)。不完整類型的數(shù)組可以通過幾種方式補充完整才能使用,大括號形式的初始化就是其中一種方式:int a[] = {10, 20};
???????? 柔性數(shù)組成員(flexible array member):也叫收縮性數(shù)組成員,這種代碼結構產(chǎn)生于對動態(tài)結構體的需求。C99使用不完整類型實現(xiàn)柔性數(shù)組成員,在C99中,結構中的最后一個元素允許是未知大小的數(shù)組,這就叫柔性數(shù)組成員。但結構中的柔性數(shù)組成員前面必須至少一個其它成員。柔性數(shù)組成員允許結構中包含一個大小可變的數(shù)組。柔性數(shù)組成員只作為一個符號地址存在,而且必須是結構體的最后一個成員,sizefo返回的這種結構大小不包括柔性數(shù)組的內存。柔性數(shù)組成員不僅可以用于字符數(shù)組,還可以是元素為其它類型的數(shù)組。包含柔性數(shù)組成員的結構用malloc()函數(shù)進行內存的動態(tài)分配,并且分配的內存應該大于結構的大小,以適應柔性數(shù)組的預期大小。
???????? C/C++標準規(guī)定不能定義長度為0的數(shù)組,因此,有些編譯器就把0長度的數(shù)組成員作為自己的非標準擴展。
示例代碼:
#include <iostream>
using namespace std;typedef struct _FlexibleArray
{char ch;int arr[0];//int arr[];//int arr[1];
}FlexibleArray;int main()
{cout<<sizeof(FlexibleArray)<<endl;const int LENGTH = 10;FlexibleArray* flexibleArray = (FlexibleArray*)new char[sizeof(FlexibleArray) + LENGTH * sizeof(int)];for (int i = 0; i < LENGTH; i ++) {flexibleArray->arr[i] = i * i;}for (int i = 0; i < LENGTH; i ++) {cout<<flexibleArray->arr[i]<<endl;}delete [] flexibleArray;return 0;
}
參考文獻:
1、? http://blog.chinaunix.net/uid-26750459-id-3191136.html
2、? http://blog.csdn.net/ce123_zhouwei/article/details/8973073
3、?http://blog.csdn.net/code_crash/article/details/4854939
總結
以上是生活随笔為你收集整理的结构体中最后一个成员为[0]或[1]长度数组(柔性数组成员)的用法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 设计模式之桥接模式(Bridge)摘录
- 下一篇: 设计模式之简单工厂模式(Simply F