深入淺出變長結構體

2021-09-30 17:13:55 字數 2475 閱讀 8297

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!

深入淺出變長結構體

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 ...