分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!
深入淺出變長結構體
1、 問題的引出
專案中用到資料報的處理,但包的大小是不固定的,其長度由包頭的2位元組決定。比如如下的包頭:88 0f 0a ob cd ef 23 00 。長度由頭2個位元組880f決定,考慮位元組序,轉為0f88,轉為10進製3976個位元組的包長度。
這個時候儲存包的時候,一方面可以考慮設定包的大小固定:如4k=4*1024=4096個位元組,因為最大包長不可能超過4k,但該方法的有缺陷,存在一種極端就是包最小僅含包頭不含資料域,此時包為8個位元組,浪費了4096-8 =4088個位元組的儲存空間。另一方面考慮有沒有一種方法能根據長度進行儲存,或者說初始不分配長度,計算出了長度後再分配儲存呢。而實際專案中正是通過包頭計算出了包的整體大小的。
這就引出了變長結構體的概念。
2、 什麼叫變長結構體?
如下所示:
struct
var_len_struct;
那結構體是怎麼實現可變長的呢?如上所示,請注意看結構體中的最後乙個元素,乙個沒有元素的陣列。我們可以通過動態開闢乙個比結構體大的空間,然後讓buffer去指向那些額外的空間,這樣就可以實現可變長的結構體了。更為巧妙的是,我們甚至可以用nsize儲存字串buffer的長度。
並且,上述的結構體可以擴充套件,比如筆者專案中遇到的儲存資料報,前面可能類似包頭的部分(儲存型別、長度等資訊),而後面buffer則儲存資料部分。
同時,需要引起注意的:iso/iec 9899-1999裡面,這麼寫是非法的,這個僅僅是gnu c的擴充套件,gcc可以允許這一語法現象的存在。但最新的c/c++不知道是否可以,我沒有測試過。c99允許。
3、變長結構體的好處體現在哪?
可能有的同學會問到,1引出部分如果說定義定長陣列浪費空間,定義乙個指標不也能指向變長的資料域部分嗎?
是的,是可以實現的。那麼我們就對比下有什麼不同。
結構體1:s_one,用指標指向資料域部分;
結構體2:s_two, 用[0]的陣列;
結構體3:s_three, 因為有的編譯器不支援[0],我們用[1]來表示;多了些儲存。
#include
#include
using
namespace
std; const
int buf_size = 100; struct
s_one; struct
s_two; struct
s_three; int
main
() cout
<< "free(p_sone) successed!"
<< endl;} if(null != p_stwo) if(null != p_sthree) return0;}
筆者vc6.0的編譯器會有如下的警告:
執行結果如下:
對比結果,我們能發現:
<1> 儲存大小方面:s_two的儲存較s_one、s_three都要少,[0]的好處,即用指標的方式需要多開闢儲存空間的。
<2> 資料連續儲存方面:s_one明顯資料域是單獨開闢的空間,與前的nsize不在連續的儲存區域,而s_two,s_three則在連續的儲存空間下。
<3>釋放記憶體方面:顯然s_one的指標的方式,需要先釋放資料域部分,才能釋放指向結構體的指標變數;而s_two,s_three可以直接釋放。
總結如下:
結構體最後使用0或1的長度陣列的原因,主要是為了方便的管理記憶體緩衝區,如果你直接使用指標而不使用陣列,那麼,你在分配記憶體緩衝區時,就必須分配結構體一次,然後再分配結構體內的指標一次,(而此時分配的記憶體已經與結構體的記憶體不連續了,所以要分別管理即申請和釋放)。
而如果使用陣列,那麼只需要一次就可以全部分配出來,反過來,釋放時也是一樣,使用陣列,一次釋放,使用指標,得先釋放結構體內的指標,再釋放結構體。還不能顛倒次序。
其實變長結構體就是分配一段連續的的記憶體,減少記憶體的碎片化,簡化記憶體的管理。
4、變長結構體的應用
<1>socket通訊資料報的傳輸;
<2>解析資料報,如筆者遇到的問題。
<3>其他可以節省空間,連續儲存的地方等。
未盡事宜,後續補上……
2013/9/22pm21:36思於家中床前
如果感覺本文對您有幫助,『頂』支援一下,您的支援是我堅持寫作最大的動力,謝謝!
給我老師的人工智慧教程打call!
深入淺出理解linux inode結構
一 inode是什麼?參考文件 做android底層驅動或者嵌入式linux的程式猿經常會遇到乙個叫inode的結構體,該結構體非常的重要,但是也比較難懂,所以寫一篇理解該inode結構的部落格是非常的有必要,廢話不多說,先看inode結構體的定義!struct inode 索引節點物件由inode...
深入淺出sizeof
int佔 位元組,short佔 位元組 1.0 回答下列問題 答案在文章末尾 1.sizeof char 2.sizeof a 3.sizeof a 4.strlen a 如果你答對了全部四道題,那麼你可以不用細看下面關於sizeof的論述。如果你答錯了部分題目,那麼就跟著我來一起 關於sizeof...
深入淺出ShellExecute
ipconfig c log.txt應如何處理?二樓的朋友,開啟拔號網路這樣 shellexecute null,open c windows rundll32.exe shell32.dll,control rundll c windows system telephon.cpl null,sw ...