c 之 柔性陣列

2021-10-24 15:26:00 字數 1629 閱讀 7503

今天看到乙個有趣的知識點,在這裡分享下。

可以直接 閱讀原文

#includestruct test0

;struct test1

;int main(void)

在64位機器上編譯執行結果:

16

8

是不是感覺到不可思議。往下看。

對於test0的結果是16,通常沒有什麼疑問,畢竟4(int)+4(int)+8(指標)= 16,但是對於後者的結構體占用空間為8位元組,有的讀者可能會有疑問。

實際上這是在c99中引入的柔性陣列的特性。即結構體的最後乙個成員,可以不完整型別(一種缺乏足夠的資訊去描述乙個完整物件的型別)的陣列,但它使得整個結構體的大小就像沒有這個成員一樣。但是呢,當用結構體通過這個名字訪問這個成員時,就像訪問乙個普通陣列成員一樣。

如果陣列最終乙個元素都沒有的話,那麼訪問這個陣列將會是未定義行為了。

記憶體申請和釋放

假設分別使用兩種型別的結構體,儲存16位元組的字元資料,需要申請記憶體。對於struct test0:

strcut test0 *t0 = malloc(sizeof(struct test0));//為結構體申請記憶體

t0->c = malloc(sizeof(char) * 16);//為成員指向的資料申請記憶體

而對於struct test1:

strcut test1 *t1 = malloc(sizeof(struct test1) + sizeof(char) * 16);

t1->c,和普通成員無異。

要判斷它們的位址是否連續也非常簡單,只需要分別列印b和c的位址就可以了。

和記憶體釋放類似,前面需要單獨釋放成員c申請的記憶體,而後者可以一起釋放。

資料拷貝

正由於前面的差別,導致資料拷貝時,更有區別。

對於struct test0:

//memcpy(t0copy,t0,sizeof(struct test0));//不可,這樣直接t0copy的c和t0的c指向同一片記憶體區域。

t0copy.a = t0.a;

t0copy.b = t0.b;

memcpy(t0copy.c,t0.c,sizeof(char)*16);

這裡無法一次拷貝,因為它的成員c是乙個指標型別,我們需要的是乙份完整拷貝,因此必須拷貝它指向的記憶體。

但是對於struct test1:

memcpy(t0copy,t0,sizeof(strcut test1) + sizeof(char) * 16);

在這裡,由於柔性陣列的記憶體,它的資料內容和結構體資料成員的位址是連續的,因此可以直接拷貝。

減少記憶體碎片

由於結構體的柔性陣列和結構體成員的位址是連續的,即可一同申請記憶體,因此更大程度地避免了記憶體碎片。另外由於該成員本身不佔結構體空間,因此,整體而言,比普通的陣列成員占用空間要會稍微小點。

**差別

c柔性陣列

一 定義 c99及以上標準支援 標準示例如下 typedef struct st type type a 初始大小為sizeof i 0個元素的陣列沒有占用空間,而後我們可以進行變長操作了。通過如下表示式給結構體分配記憶體 type a p type a malloc sizeof type a 1...

C語言 柔性陣列

柔性陣列 flexible array 也叫伸縮性陣列,其實就是變長陣列,反映了c語言對精煉 的極致追求。這種 結構產生於對動態結構體的需求。比如我們需要在結構體中存放乙個動態長度的字串,這時候,柔性陣列可以大顯身手了。c99使用不完整型別來實現柔性陣列,標準形式如下 struct mystruct...

C語言柔性陣列

1 柔性陣列 c語言中結構體的最後乙個元素可以是大小未知的陣列 c語言中可以由結構體產生柔性陣列 typedef struct soft array softarray 可以試試,printf d sizeof softarray 列印出它的sizeof 大小 結果是4,也就是說array這個未知長...