C語言-0位元組長度陣列的使用
阿新 • • 發佈:2021-01-11
奇怪的知識又增加了-0位元組長度陣列的使用
引言
最近看了一些網路程式設計的書,學到了一些C語言的“奇巧淫技”,遂開此欄目,進行記載。
問題引出:
試求以下兩個結構體的長度,並簡述如何使用這種0位元組長度的陣列
typedef struct zero_byte_buffer1 { uint8_t status; int len; char data[0]; } zero_byte_buffer1_t; typedef struct zero_byte_buffer2 { uint8_t status; uint8_t len; uint32_t data[0]; } zero_byte_buffer2_t;
測試程式與結果分析
GNU C中提供了這種0長度陣列的支援,只要將0長度陣列放在結構體的末尾就可以在支援GNU C的編譯器中編譯通過上述結構體,並方便的使用它們。
當然學習這種“奇巧淫技”的最好方法就是測試它、對比它,知其然知其所以然,就能化為己用,上程式碼:
/* Zero_byte_array */ #include <stdio.h> #include <string.h> #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "sdkconfig.h" #define MAX_LENGTH 1024 #define CURRENT_LENGTH 3 typedef struct zero_byte_buffer1 { uint8_t status; int len; char data[0]; } zero_byte_buffer1_t; typedef struct zero_byte_buffer2 { uint8_t status; uint8_t len; uint32_t data[0]; } zero_byte_buffer2_t; typedef struct fixed_length_buffer { int len; char data[MAX_LENGTH]; } fixed_length_buffer_t; typedef struct variable_length_buffer { int len; char *data; } variable_length_buffer_t; void app_main(void) { printf("TEST Begin\r\n"); zero_byte_buffer1_t* zero_byte_buffer1; fixed_length_buffer_t* fixed_length_buffer; variable_length_buffer_t* variable_length_buffer; printf("zero_byte_buffer1 length is %d\r\n", sizeof(zero_byte_buffer1_t)); printf("zero_byte_buffer2 length is %d\r\n", sizeof(zero_byte_buffer2_t)); printf("fixed_length_buffer length is %d\r\n", sizeof(fixed_length_buffer_t)); printf("variable_length_buffer length is %d\r\n", sizeof(variable_length_buffer_t)); /*use zero_byte_buffer*/ /*1. malloc*/ if ((zero_byte_buffer1 = (zero_byte_buffer1_t *)malloc(sizeof(zero_byte_buffer1_t) + sizeof(char) * CURRENT_LENGTH)) != NULL) { zero_byte_buffer1->len = CURRENT_LENGTH; memcpy(zero_byte_buffer1->data, "OK", CURRENT_LENGTH); printf("%d, %s\n", zero_byte_buffer1->len, zero_byte_buffer1->data); } /*2. free*/ free(zero_byte_buffer1); zero_byte_buffer1 = NULL; /*use fixed_length_buffer*/ /*1. malloc*/ if ((fixed_length_buffer = (fixed_length_buffer_t *)malloc(sizeof(fixed_length_buffer_t))) != NULL) { fixed_length_buffer->len = CURRENT_LENGTH; memcpy(fixed_length_buffer->data, "OK", CURRENT_LENGTH); printf("%d, %s\n", fixed_length_buffer->len, fixed_length_buffer->data); } /*2. free*/ free(fixed_length_buffer); fixed_length_buffer = NULL; /*use fixed_length_buffer*/ /*1. malloc*/ if ((variable_length_buffer = (variable_length_buffer_t *)malloc(sizeof(variable_length_buffer_t))) != NULL) { variable_length_buffer->len = CURRENT_LENGTH; if ((variable_length_buffer->data = (char *)malloc(sizeof(char) * CURRENT_LENGTH)) != NULL) { memcpy(variable_length_buffer->data, "OK", CURRENT_LENGTH); printf("%d, %s\n", variable_length_buffer->len, variable_length_buffer->data); } } /*2. free*/ free(variable_length_buffer->data); free(variable_length_buffer); variable_length_buffer = NULL; }
編譯執行結果:
TEST Begin
zero_byte_buffer1 length is 8
zero_byte_buffer2 length is 4
fixed_length_buffer length is 1028
variable_length_buffer length is 8
3, OK
3, OK
3, OK
通過測試結果可以發現:
1.比較zero_byte_buffer1 length is 8 和zero_byte_buffer2 length is 4兩條測試結果可知
0位元組長度的陣列,自己本身並不佔用結構體的空間,但是會影響結構體的位元組對齊。
2.什麼時間使用0位元組長度的陣列呢?
這種可變長的buffer型別的好處是:
1)相比使用定長陣列的buffer ,即fixed_length_buffe,其data的長度是可變的,可根據當前實際的data的長度進行靈活的申請需要的空間。
2)相比於使用變長陣列的buffer,即variable_length_buffer,其節省了一個malloc 、free時的操作步驟,即variable_length_buffer需要兩次malloc、兩次free,但zero_byte_buffer只需一次malloc和一次free。
(謝謝點贊或收藏,比心)