柔性陣列(0長度陣列)

2021-10-22 01:30:36 字數 2928 閱讀 5308

柔性陣列這個概念相信大多數人博友都沒有聽說過,但是它確實存在。

在c99中,結構(結構體)的最後乙個元素允許是未知大小的陣列,這就叫做柔性陣列成員。

比如:

struct s

;

或者是:

struct s

;

一、結構中柔性陣列成員前面必須至少有乙個其他成員比如,當你建立含有柔性陣列成員的結構體時,結構體成員不能單單只有乙個柔性陣列成員:

struct er

;//error

除了柔性陣列成員之外,結構體成員中應該至少再包含乙個其他非柔性陣列成員。

二、sizeof返回的這種結構大小不包括柔性陣列的記憶體

所以,當你用sizeof來計算乙個含有柔性陣列成員的結構體大小時,計算出的結果不包括柔性陣列成員在內。

比如:

#include

struct s

;int

main()

三、包含柔性陣列成員的結構用malloc函式進行記憶體的的動態分配,並且分配的記憶體應該大於結構的大小,以適應柔性陣列的預期大小比如,對於該結構體:

struct s

;

你想用他的柔性陣列成員存放5個整型元素,那麼你應該這樣開闢空間:

我們可以利用柔性陣列實現以下功能:

要求:用結構體將數字100和0~4五個數字進行封裝。

要求改為:用結構體將數字100和0~9十個數字進行封裝。

#include

#include

struct s

;int

main()

//調整所開闢的動態記憶體空間的大小

struct s* ptr =

realloc

(ps,

sizeof

(struct s)+10

*sizeof

(int))

;if(ptr !=

null

)//開闢成功

for(i =

5; i <

10; i++

)//釋放開闢的動態記憶體空間

free

(ps)

; ps =

null

;return0;

}

注意:柔性陣列的使用與動態開闢記憶體的知識密不可分。其實,我們若不借用柔性陣列也能實現以上功能:

#include

#include

struct s

;int

main()

//調整所開闢的動態記憶體空間的大小

int* ptr =

(int*)

realloc

(ps->arr,10*

sizeof

(int))

;if(ptr !=

null

)//開闢成功

for(i =

5; i <

10; i++

)//釋放開闢的動態記憶體空間

free

(ps->arr)

; ps->arr =

null

;free

(ps)

; ps =

null

;return0;

}

柔性陣列其實也就是結構體中的乙個陣列,準確來說,是乙個空間大小可以自由變換的陣列,那麼我們在結構體中定義乙個指標,使指標指向的空間可以自由變換(即指標指向的是動態開闢的記憶體),也就達到了這個效果。

注意:這裡釋放動態記憶體空間時,需要先釋放ps->arr指向的動態記憶體空間,再釋放ps指向的動態記憶體空間。如果我們先釋放的是ps指向的動態記憶體空間,那麼ps->arr所指向的空間就再也找不到了。

一、方便記憶體釋放

我們可以看到,用柔性陣列解決這個問題的時候,我們只需要釋放一次動態記憶體。而模擬實現柔性陣列的時候,我們需要釋放兩次動態記憶體,最重要的是這兩次釋放記憶體的順序還不能顛倒,如若顛倒了釋放順序就會導致有一塊動態開闢的記憶體空間不能得到釋放,最終導致記憶體洩漏。

二、有益於提高訪問速度,也有益於減少記憶體碎片

其實第一種用柔性陣列解決問題的時候,記憶體中開闢的空間是連續的:

而第二種模擬實現柔性陣列的方法,在開闢記憶體的時候差不多是這樣的:

看似在分配記憶體的時候連續還是不連續好像沒什麼影響,但是你是否知道有乙個概念叫記憶體碎片。

越多的不連續記憶體分配會產生越多的記憶體碎片,記憶體碎片越多,我們對記憶體的利用率就越低下,所以我們應該盡量避免不連續的記憶體分配。

其次,cpu在向儲存器中提取資料時,會遵循區域性性原理。

區域性性原理: cpu訪問儲存器時,無論是訪問指令還是訪問資料,所訪問的儲存單元都趨於聚集在乙個較小的連續區域中。

所以,將相關聯的資料儲存在一起(即連續儲存),會提高cpu的訪問速度。

0 長度陣列

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

0長度陣列問題

標準c c 不支援0長度陣列,gnu支援 struct node int main int argc,char argv 上述 輸出為12,0長度陣列不占用記憶體空間 中e表示乙個常量指標,這個特性由編譯器來實現的,故具有不可移植性 對於這個用法,我們定義的結構體指標可以指向任意長度的記憶體buff...

結構體0長度陣列的作用

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