C語言變長訊息定義:柔性數組,柔性數組
在遊戲前後端交換的過程中,經常會用到變成的訊息體,因為有的內容的大小是位置的,例如一條微博,微博的內容大小是未知的。
一般的做法是定義一個char*類型的指標,然後指定其長度,代碼如下:
typedef struct{unsigned len;char* pData;}Msg;
使用的時候是這樣的:
char str[] = "hello world!";unsigned len = sizeof(str);Msg* m = (Msg*)malloc(sizeof(Msg)+len*sizeof(char));m->len = len;m->pData = (char*)(m+1);memcpy(m+1, str, len);printf("%d, %s\n", m->len, m->pData);
有沒有覺得時機上char* pData很多餘呢?
因為資料時機的儲存位置在m+1,我們可以直接得到這個指標,而不需要重新定義一個char* pData來報錯這個位置。
這樣帶來了另一個問題就是,訪問不方便,我們不能用結構體成員的方式來訪問了,可以使用柔性數組,且看:
typedef struct{unsigned len;char data[];}Message;
使用起來就是這樣的:
Message* msg = (Message*)malloc(sizeof(Message) + len*sizeof(char));msg->len = len;memcpy(msg->data, str, len);printf("%d, %s\n", msg->len, msg->data);free(msg);
來分完整代碼對比下:
// array0.h
typedef struct{unsigned len;char* pData;}Msg;typedef struct{unsigned len;char data[];}Message;
// main.c
// test for 0 size array#include <stdio.h>#include <stdlib.h>#include <string.h>#include "array0.h"int main(){char str[] = "hello world!";unsigned len = sizeof(str);// 普通用法Msg* m = (Msg*)malloc(sizeof(Msg)+len*sizeof(char));m->len = len;m->pData = (char*)(m+1);memcpy(m+1, str, len);printf("%d, %s\n", m->len, m->pData);free(m);// 柔性數組Message* msg = (Message*)malloc(sizeof(Message) + len*sizeof(char));msg->len = len;memcpy(msg->data, str, len);printf("%d, %s\n", msg->len, msg->data);free(msg);system("pause");return 0;}