首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> 關於C

C 指標進階(25):結構體與 malloc 動態記憶體技巧——訊息佇列實戰

     編輯:關於C

核心技巧:柔性陣列成員

Linux 核心訊息佇列使用的 struct msgbuf 定義:

struct msgbuf {
    long mtype;      // 訊息類型
    char mtext[1];   // 柔性陣列:實際長度由 malloc 決定
};

關鍵點:mtext[1] 只有 1 字元,但透過 malloc(sizeof(struct msgbuf) + extra_len) 分配額外空間,即可存放任意長度訊息。這是 C99 標準化前的經典「柔性陣列」寫法(C99 可寫 char mtext[];)。

完整範例:System V 訊息佇列收發

發送端 msgsnd.c

#define _GNU_SOURCE
#include 
#include 
#include 
#include 
#include 
#include 

#define QUE_ID 2

int main(void) {
    int qid = msgget(QUE_ID, IPC_CREAT | 0600);
    if (qid == -1) { perror("msgget"); exit(1); }
    printf("Queue %d created\n", qid);

    // 分配結構體 + 100 字節訊息空間
    struct msgbuf *msg = malloc(sizeof(struct msgbuf) + 100);
    msg->mtype = 1;
    strcpy(msg->mtext, "deepfuture.iteye.com");

    // 發送:最後參數 0 表阻塞等待
    if (msgsnd(qid, msg, 100, 0) == -1) { perror("msgsnd"); exit(1); }
    printf("Message sent\n");
    free(msg);
    return 0;
}

接收端 msgrcv.c

#define _GNU_SOURCE
#include 
#include 
#include 
#include 
#include 

#define QUE_ID 2

int main(void) {
    int qid = msgget(QUE_ID, 0); // 不建立,只取得
    if (qid == -1) { perror("msgget"); exit(1); }

    struct msgbuf *msg = malloc(sizeof(struct msgbuf) + 100);
    // 接收類型 0 表任意類型,IPC_NOWAIT 非阻塞
    if (msgrcv(qid, msg, 101, 0, 0) == -1) { perror("msgrcv"); exit(1); }
    printf("Received: %s\n", msg->mtext);
    free(msg);
    return 0;
}

編譯與執行

gcc msgsnd.c -o msgsnd
gcc msgrcv.c -o msgrcv
./msgsnd   # 先執行發送
./msgrcv   # 再執行接收,輸出 "deepfuture.iteye.com"

記憶體佈局圖解

struct msgbuf (malloc 區塊)
+----------------+------------------+
| long mtype (8B)| char mtext[100]  |  <- 實際可用 100 字節
+----------------+------------------+
^                ^
msg              msg->mtext

進階應用:自定義緩衝區結構

typedef struct {
    uint32_t len;      // 資料長度
    uint8_t  data[];   // C99 柔性陣列
} buffer_t;

// 分配 1KB 緩衝區
buffer_t *buf = malloc(sizeof(buffer_t) + 1024);
buf->len = 1024;
// 直接操作 buf->data[0...1023]

此模式廣泛用於網路封包、驅動程式 DMA 緩衝區、共享記憶體等場景。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved