0長度陣列的使用,重點掌握的知識

2021-09-28 18:00:07 字數 2912 閱讀 6164

0長度的陣列在iso c和c++的規格說明書中是不允許的,但是gcc的c99支援的這種用法。

gcc對0長度陣列的文件參考:「arrays of length zero」

如下**片段,哪個更簡潔更靈活,看一眼就知道了:

#include #include typedef struct tagarray  

array_s;

typedef struct tagpointer

pointer_s;

int main()

parray->length = array_length;

memset(parray->contents, 'a', array_length);

free(parray);

ppointer = (pointer_s*)malloc(sizeof(pointer_s));

if(ppointer == null)

memset(ppointer, 0, sizeof(pointer_s));

ppointer->length = array_length;

ppointer->contents = (char*)malloc(array_length);

if (ppointer->contents == null)

memset(ppointer->contents, 'a', array_length);

free(ppointer->contents);

free(ppointer);

return 0;

}

第一種結構體的定義:想給乙個結構體內的資料分配乙個連續的記憶體,有兩個好處:

(1)方便記憶體釋放。

如果我們的**提供給別人使用,你在裡面做了二次記憶體分配,並把整個結構體返回給使用者。

使用者呼叫free可以釋放結構體,但是使用者並不知道這個結構體內的成員也需要free,所以你不能指望使用者來發現這個事。

所以,如果我們把結構體的記憶體以及其成員要的記憶體一次性分配好了,並返回給使用者乙個結構體指標,使用者做一次free就可以把所有的記憶體也給釋放掉。

(2)有利於訪問速度。

連續的記憶體有益於提高訪問速度,也有益於減少記憶體碎片。

第二種結構體的使用:需要分配兩次記憶體以及釋放兩次記憶體,在檢查申請記憶體成功與否的**量上看也明顯沒有第一種更簡潔。

看看記憶體是怎麼個連續的,用gdb的x命令來檢視:(array_s中的那個char contents不占用結構體的記憶體,

所以array_s就只有乙個int成員,4個位元組,而我們還要為contents分配10個位元組長度,所以,一共是14個位元組):

1 (gdb) p parray 

2 $1 = (array_s *) 0x804b008

3 (gdb) p *parray

4 $2 =

5 (gdb) p parray ->contents

6 $3 = 0x804b00c "aaaaaaaaaa"

7 (gdb) x/14b parray

8 0x804b008: 10 0 0 0 97 97 97 97

9 0x804b010: 97 97 97 97 97 97

從上面的記憶體布局我們可以看到,前4個位元組是 int length,後10個位元組就是char contents。

如果用指標的話,會變成這個樣子:

10 (gdb) p ppointer

11 $4 = (pointer_s *) 0x804b020

12 (gdb) p *ppointer

13 $5 =

14 (gdb) p ppointer ->contents

15 $6 = 0x804b030 "aaaaaaaaaa"

16 (gdb) x/16b ppointer

17 0x804b020: 10 0 0 0 48 -80 4 8

18 0x804b028: 0 0 0 0 17 0 0 0

19 (gdb) x/10b ppointer ->contents

20 0x804b030: 97 97 97 97 97 97 97 97

21 0x804b038: 97 97

22 (gdb) x/16x ppointer

23 0x804b020: 0x0a 0x00 0x00 0x00 0x30 0xb0 0x04 0x08

24 0x804b028: 0x00 0x00 0x00 0x00 0x11 0x00 0x00 0x00

第17行前四個位元組是 int length,後四個位元組是contents的位址。

第23行以16進製制顯示,位址是: 0x30 0xb0 0x04 0x08, 即:0x0804b030。

第20行和第21行是char* contents指向的內容。 疑問

為什麼不使用指標來代替零長度陣列:

大家在各種場合,可能常常會看到這樣的字眼:陣列名在作為函式引數進行引數傳遞時,就相當於是乙個指標。在這裡,我們千萬別被這句話迷惑了:陣列名在作為函式引數傳遞時,確實傳遞的是乙個位址,但陣列名絕不是指標,兩者不是同乙個東西。陣列名用來表徵一塊連續記憶體儲存空間的位址,而指標是乙個變數,編譯器要給它單獨再分配乙個記憶體空間,用來存放它指向的變數的位址。

結構體0長度陣列的作用

在標準 c 和 c 中,不允許用 0 長度陣列,但在 gnu c 中,卻可以定義 0 長度陣列。比如 引用 struct line 0 長度陣列不占有空間,從列印 sizeof struct line 可以看到這個結構體的長度為 4,這 4 位元組空間屬於整型量 length 那麼結構體裡最後的 0...

C語言 0位元組長度陣列的使用

最近看了一些網路程式設計的書,學到了一些c語言的 奇巧淫技 遂開此欄目,進行記載。問題引出 試求以下兩個結構體的長度,並簡述如何使用這種0位元組長度的陣列 typedef struct zero byte buffer1 zero byte buffer1 t typedef struct zero...

gnu c 長度為0的陣列的使用

長度為的陣列在標準c和c 中是不允許的,如果使用長度為的陣列,編譯時會產生錯誤,提示陣列長度不能為。但在gnuc中,這種用法卻是合法的。它的最典型的用法就是位於陣列中的最後一項。struct description struct description thisline struct descrip...