先說說我的理解:
struct example __attribute ((packed));
1. 存在的意義:當結構體的長度變長時,例如裡面有乙個字串時,為了方便管理記憶體。
這個結構體不要用struct example a的方式定義, 而應用struct example *a; a = (struct example *)malloc(sizeof(struct example) + extrasize);的形式。extrasize是想額外申請的空間,就是字串的長度。
2. 如何使用裡面的資料?
前面的資料項不用說了,後面的tag_data直接就是我們申請的額外的位址的開始位址。所以,很好用
3. 如何釋放申請的位址空間?
直接free(a)就好。有些人可能認為後面的空間沒有釋放,其實不然。因為malloc申請的空間系統是需要進行管理的,你申請了多少,當你釋放的時候,就釋放多少。並不是根據你的資料型別來的,否則你說 char *p; p = malloc(20); 然後free(p);系統該釋放多少空間呢。 至於系統如何管理的,貌似是通過乙個鍊錶進行的,記不清了。
4. 附1
為了解決這個疑惑,後來看了幾篇文章,感謝他們。
後來就是人提到過有些編譯器不支援0長陣列,那怎麼辦呢?很簡單,將陣列長度定為1即可,這樣僅僅浪費乙個位元組的空間(位元組對齊的話另當別論)。這樣做還有另外乙個好處就是不用記錄這個字串的長度, 因為本來就存了乙個位元組的空間,可用這乙個位元組的空間來標識這個字串是否為空。
5.附2
有人可能會問,為什麼最後乙個資料項不設定成乙個指標呢?char tag_data[0]; 和char *tag_data;有什麼區別呢?
第乙個問題:最好不要設定成指標,因為這樣的話,你得為tag_data指標重新申請空間,申請的空間還不連續;其次,釋放的時候很麻煩,必須先釋放內部的指標,但是這個往往是人最容易忽略而造成記憶體呢洩露的原因。
指標和陣列很多人都把他們之間畫成等號了,這是個錯誤,希望各位不要犯。他們倆只有在作為函式引數的時候才是真正的一摸一樣,都是指標變數,其他情況都不一樣。最大的區別:陣列是直接定址的,指標是間接定址的。array[0]中, array 是乙個常量,等於&(a[0]); 而指標變數是乙個變數。像array = a就不允許賦值(常量怎麼可能作為賦值運算子的左運算元呢?),a = array就是允許的。
6.最後
這個東西用在記憶體池的管理中用得很多。記憶體池,這個東西,說起來很嚇唬人,其實就是那麼回事。乙個程式或者動態庫維護的乙個全域性的陣列而已,無它。比如說乙個c/s架構的伺服器,客戶端呼叫乙個預先編好的動態庫中的函式,一般來說不會沒發乙個請求網路就幫你投遞過去,那樣資料太小了。一般都是在動態庫中維護乙個陣列,把請求往裡面填,填到滿的時候傳送出去;或者使用者強行要求傳送出去。
這個就跟標準i/o庫很像了,其實裡面也是一段快取,通過這個快取使得記憶體和外存的資料交換不是那麼頻繁,提高了效率。使用者也可以使用fflush()函式強行寫到外存。原理都是類似的。
經常遇到的結構形狀如下:
struct在這個結構中,data是乙個陣列名;但該陣列沒有元素;該陣列的真實位址緊隨結構體buffer之後,而這個位址就是結構體後面資料的位址(如果給這個結構體分配的內容大於這個結構體實際大小,後面多餘的部分就是這個data的內容);這種宣告方法可以巧妙的實現c語言裡的陣列擴充套件。buffer
;
寫個程式對比char data[0],char *data, char data,如下所示:
從結果可以看出data[0]和data不占用空間,且位址緊跟在結構後面,而char *data作為指標,占用4個位元組,位址不在結構之後。
3、實際當中的用法
在實際程式中,資料的長度很多是未知的,這樣通過變長的陣列可以方便的節省空間。對指標操作,方便資料型別的轉換。測試程式如下:
程式執行結果如下:#include #include #include #include typedef struct
buff_st_1;typedef struct
buff_st_2;
typedef struct
buff_st_3;
typedef struct
student_st;
void print_stu(const student_st *stu)
int main()
採用char *data,需要進行二次分配,操作比較麻煩,很容易造成記憶體洩漏。而直接採用變長的陣列,只需要分配一次,然後進行取值即可以。
C語言中strdup函式使用方法
標頭檔案 include 定義函式 char strdup const char s 函式說明 strdup 會先用malloc 配置與引數s 字串相同的空間大小,然後將引數s 字串的內容複製到該記憶體位址,然後把該位址返回。該位址最後可以利用free 來釋放。返回值 返回一字串指標,該指標指向複製...
C語言中fflush函式的使用方法
此函式包含在stdio.h標頭檔案中,用來強制將緩衝區中的內容寫入檔案。函式原型 int fflush file stream 函式功能 清除乙個流,即清除檔案緩衝區,當檔案以寫方式開啟時,將緩衝區內容寫入檔案。也就是說,對於ansi c規定的是緩衝檔案系統,函式fflush用於將緩衝區的內容輸出到...
C語言中fflush函式的使用方法
此函式包含在stdio.h標頭檔案中,用來強制將緩衝區中的內容寫入檔案。函式原型 int fflush file stream 函式功能 清除乙個流,即清除檔案緩衝區,當檔案以寫方式開啟時,將緩衝區內容寫入檔案。也就是說,對於ansi c規定的是緩衝檔案系統,函式fflush用於將緩衝區的內容輸出到...