Flexible Array Members trong C: Ứng dụng và kỹ thuật thực tiễn

Đặc điểm của Flexible Array Members

Flexible Array Members (FAM) là tính năng được thêm vào C99 cho phép khai báo mảng không xác định kích thước trong cấu trúc dữ liệu. Đặc điểm nổi bật:

  • Kích thước xác định tại thời điểm chạy
  • Không chiếm không gian cố định trong cấu trúc
  • Phải là thành viên cuối cùng của struct

Ví dụ minh họa

Xét cấu trúc Document sau:


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
    char docTitle[100];
    char docAuthor[50];
    char content[]; // Flexible array member
} Document;

int main() {
    const char* title = "Hướng dẫn C nâng cao";
    const char* author = "Nguyen Van A";
    const char* body = "Chương 1: Quản lý bộ nhớ...";

    size_t size = sizeof(Document) + strlen(body) + 1;
    Document* doc = malloc(size);

    if (doc) {
        strcpy(doc->docTitle, title);
        strcpy(doc->docAuthor, author);
        strcpy(doc->content, body);

        printf("Tài liệu: %s\n", doc->docTitle);
        printf("Nội dung: %s\n", doc->content);

        free(doc);
    }
    return 0;
}

Quy tắc sử dụng

  1. Vị trí bắt buộc: FAM phải là thành viên cuối cùng trong struct
  2. Cấp phát bộ nhớ: Tính toán tổng kích thước = sizeof(struct) + kích thước mảng
  3. Giải phóng: Chỉ cần free() toàn bộ cấu trúc

So sánh với mảng thông thường

Flexible ArrayMảng cố định
Kích thước thay đổiKích thước cố định
Tối ưu bộ nhớCó thể gây lãng phí
Cấp phát độngCấp phát tĩnh

Ứng dụng nâng cao

1. Bộ đệm động


typedef struct {
    int bufferSize;
    char bufferData[];
} DynamicBuffer;

DynamicBuffer* createBuffer(int size) {
    DynamicBuffer* buf = malloc(sizeof(DynamicBuffer) + size);
    if (buf) buf->bufferSize = size;
    return buf;
}

2. Cấu trúc lồng nhau


typedef struct {
    char name[40];
    char bio[];
} UserProfile;

typedef struct {
    int userCount;
    UserProfile users[];
} UserDatabase;

// Cấp phát cơ sở dữ liệu người dùng
size_t total = sizeof(UserDatabase) + 2 * sizeof(UserProfile) + 200;
UserDatabase* db = malloc(total);

Nguyên tắc an toàn

  • Kiểm tra kết quả malloc()
  • Không thêm thành viên sau FAM
  • Tránh sao chép cấu trúc bằng assignment
  • Không dùng FAM trong union

Thẻ: C programming Flexible Array Members memory management Data Structures C99 standard

Đăng vào ngày 4 tháng 7 lúc 19:39