1 #include <stdio.h>
2 #include <string.h>
3 #include "iostream"
4
5 typedef struct {
6 unsigned int dwMsgLen;
7 char ucMsg[0]; //柔性數組(零長數組) C99以上支持
8 }T_SendMsg;
9
10
11 int main(void)
12 {
13 printf("sizeof(T_SendMsg) = %d\n", sizeof(T_SendMsg));
14
15 char ucBuf[300] = {0};
16 unsigned int dwPwName = 1002;
17 unsigned int dwPwNameLen = 0;
18
19 dwPwNameLen += sprintf(ucBuf,"pw%4d",dwPwName);
20
21 T_SendMsg tSendMsg;
22 memcpy(tSendMsg.ucMsg, ucBuf, dwPwNameLen);
23
24 printf("%s\n", tSendMsg.ucMsg);
25 printf("sizeof(T_SendMsg) = %d\n", sizeof(tSendMsg));
26 return 0;
27 }
g++ flexarr.cpp -o f.out -std=c++11
【輸出】./f.out
sizeof(T_SendMsg) = 4
pw1002
sizeof(T_SendMsg) = 4
【參考】
https://blog.csdn.net/hannick/article/details/2119223
結構體最后定義一個char p[0];這樣的成員有什么意義?
這是個廣泛使用的常見技巧,常用來構成緩沖區。比起指針,用空數組有這樣的優勢:
1.不需要初始化,數組名直接就是所在的偏移
2.不占任何空間,指針需要占用int長度空間,空數組不占任何空間。
“這個數組不占用任何內存”,意味着這樣的結構節省空間;“該數組的內存地址就和他后面的元素的地址相同”,意味着無需初始化,數組名就是后面元素的地址,直接就能當做指針使用。
這樣的寫法最適合制作動態buffer。因為可以這樣分配空間:
malloc(sizeof(struct XXX)+ buff_len);
看出來好處沒有?直接就把buffer的結構體和緩沖區一塊分配了。用起來也非常方便,因為現在空數組其實變成了buff_len長度的數組了。
這樣的好處是:
一次分配解決問題,省了不少麻煩。大家知道為了防止內存泄漏,如果是分兩次分配(結構體和緩沖區),那么要是第二次malloc失敗了,必須回滾釋放第一個分配的結構體。這樣帶來了編碼麻煩。其次,分配了第二個緩沖區以后,如果結構里面用的是指針,還要為這個指針賦值。同樣,在free這個buffer的時候,用指針也要兩次free。如果用空數組,所有問題一次解決。
其次,大家知道小內存的管理是非常困難的,如果用指針,這個buffer的struct部分就是小內存了,在系統內存中多了勢必嚴重影響內存管理的性能。要是用空數組把struct和實際數據緩沖區一次分配大塊問題,就沒有這個問題。
如此看來,用空數組既簡化編碼,又解決了小內存碎片問題提高了性能,何樂不為?應該廣泛采用。
by:燦輝
