最近在準備分析linux input子系統,發現核心**裡面有很多小技巧。特此記錄下,如有不足之處,敬請指正。
在日常的程式設計中,有時候需要在結構體中存放乙個長度動態的字串,比如說,我們要在結構體中存放乙個名字,但是這個名字的長度是未知的。於是,我們就會採用以下兩種方法來解決這個問題。
注:以下的**都是在下面的平台進行驗證測試的:
linux version 2.6.32-38-generic (buildd@allspice) (gcc version 4.4.3 (ubuntu 4.4.3-4ubuntu5) ) #83-ubuntu smp wed jan 4 11:12:07 utc 2012碰到上面的情況,一般而言我們會這麼做:首先在結構體中定義乙個指標成員,然後為這個指標成員
malloc()
一定長度的空間,進而往該空間寫入字串。
#include
#include
#include
struct node;
char test_name = "testname";
int main(void)
上述**的執行結果為:
sizeof(struct node) = 16從中,我們可以看出:num addr:0x10ba010
data addr:0x10ba014
name addr:0x10ba030
name = testname
name[0] = t
name[7] = e
1、如果想要例項化test_node
,第一次要為test_node
申請大小為sizeof(struct node)
的空間,第二次再為其成員name
申請lenght
大小的空間。
首先我們要呼叫兩次malloc()
,呼叫兩次,意味著最後也要跟著free()
兩次;其次,如果第二次為name
成員申請空間失敗的話,需要返回回去將test_node
free掉。這樣工作量就上來了,而且容易導致malloc()
與free()
沒對應進而出現記憶體錯誤。
2、我們看到,sizeof(struct node)
的大小為16,即4+4+8的大小。這個可以和下面的**進行對比。
3、通過列印test_node
三個成員的位址分別為:
num addr:0x10ba010很明顯,成員data addr:0x10ba014
name addr:0x10ba030
name
的位址與成員num
和data
的位址並不是連續的。小記憶體的管理是非常困難的,如果用指標,這個name
的部分就是小記憶體了,在系統內存在多了勢必嚴重影響記憶體管理的效能。要是用空陣列把結構體和實際資料緩衝區一次分配大塊問題,就沒有這個問題。
為了規避上述**的問題,我們採用下面的方法來解決:
#include
#include
#include
struct node;
char test_name = "testname";
int main(void)
執行結果為:
sizeof(struct node) = 8通過比較,我們不難看出:num addr:0x1574010
data addr:0x1574014
name addr:0x1574018
test_node+1 addr:0x1574018
name = testname
name[0] = t
name[7] = e
1、此時,例項化test_node
只呼叫一次malloc()
,意味著最後也只要free()
一次。為其申請了乙個長度為sizeof(struct node)+lenght
的空間,所申請到的空間是連續的,沒有小記憶體的情況出現。減小了對記憶體管理效能的影響。
2、同樣的,sizeof(struct node)
為8,即4+4,因此我們可以知道這裡的成員name
並沒有占用空間,即使占用乙個指標大小的空間都沒有,因此這種方式可以節省空間。
3、此時test_node
三個成員的位址分別為:
num addr:0x1574010可以明顯的看到,這個位址是連續的。因為我們只data addr:0x1574014
name addr:0x1574018
malloc()
一次。
4、並且,我們還知道test_node+1
的位址和test_node->name
的位址是一樣的,說明兩者指向同一塊記憶體區域,這更進一步的驗證了成員name
並沒有占用空間。
c99使用不完整型別實現柔性陣列成員,在c99 中,結構中的最後乙個元素允許是未知大小的陣列,這就叫做柔性陣列(flexible array)成員(也叫伸縮性陣列成員),但結構中的柔性陣列成員前面必須至少乙個其他成員。柔性陣列成員允許結構中包含乙個大小可變的陣列。柔性陣列成員只作為乙個符號位址存在,而且必須是結構體的最後乙個成員,sizeof 返回的這種結構大小不包括柔性陣列的記憶體。柔性陣列成員不僅可以用於字元陣列,還可以是元素為其它型別的陣列。包含柔性陣列成員的結構用malloc ()函式進行記憶體的動態分配,並且分配的記憶體應該大於結構的大小,以適應柔性陣列的預期大小。
第八章 柔性陣列成員
結構體中最後乙個成員為[0]或[1]長度陣列(柔性陣列成員)的用法
零長度陣列
零長度陣列 神奇的int reserve 0 include include struct device 構題 device 之後 這種宣告方法可以巧妙的實現c語 言裡的陣列擴充套件 int main a.out p dev reserve 0 100 p dev reserve 24 0 size...
零長度陣列
適用於c語言變長陣列 在實際的程式設計中,我們經常需要使用變長陣列,但是c語言並不支援變長的陣列。此時,我們可以使用結構體的方法實現c語言變長陣列。struct mydata 在結構中,data是乙個陣列名 但該陣列沒有元素 該陣列的真實位址緊隨結構體mydata之後,而這個位址就是結構體後面資料的...
整理 零長度陣列
零長度陣列 gnu c 允許使用零長度陣列,在定義變長物件的頭結構時,這個特性非常有用。例 如 include linux minix fs.h struct minix dir entry 結構的最後乙個元素定義為零長度陣列,它不佔結構的空間。在標準 c 中則需要 定義陣列長度為 1,分配時計算物...