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

C 語言動態一維陣列:malloc 配置、存取、釋放完整範例

     編輯:關於C

前言:為什麼需要動態陣列?

  • 編譯時期大小未知 (由使用者輸入、檔案讀取、運算決定)
  • 大小可能很大,超過堆疊限制 (通常 1~8 MB)
  • 生命週期需跨越函式、或依條件釋放

標準範例:執行期決定大小的整數陣列

#include 
#include 

int main() {
    int n;

    // 1. 取得大小
    printf("請輸入陣列大小 n: ");
    if (scanf("%d", &n) != 1 || n <= 0) {
        fprintf(stderr, "無效輸入\n");
        return 1;
    }

    // 2. 配置記憶體 (堆疊)
    // malloc 回傳 void*,C 語言可隱式轉換,C++ 需強制轉型
    int *arr = malloc(n * sizeof(int));
    if (!arr) {  // 必須檢查 NULL
        perror("malloc 失敗");
        return 1;
    }

    // 3. 存取:與靜態陣列語法完全相同 arr[i]
    printf("請輸入 %d 個整數:\n", n);
    for (int i = 0; i < n; i++) {
        if (scanf("%d", &arr[i]) != 1) {
            fprintf(stderr, "輸入錯誤\n");
            free(arr);
            return 1;
        }
    }

    // 4. 使用
    printf("陣列內容:\n");
    for (int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    putchar('\n');

    // 5. 釋放 (配對 free)
    free(arr);
    arr = NULL;  // 防懸空指標 (良好習慣)

    return 0;
}

關鍵步驟圖解

堆疊 (Heap) 配置後:

arr (Stack) ──────► +------------------+
                    | arr[0]  sizeof(int) |
                    | arr[1]  sizeof(int) |
                    |   ...               |
                    | arr[n-1]            |
                    +------------------+
                    大小: n * sizeof(int) 位元組
                    位址: 8/16 位元組對齊

常見錯誤與修正

錯誤程式碼問題修正
int *arr = malloc(n);忘記乘 sizeof(int),配置位元組數而非元素數malloc(n * sizeof(int))
int *arr = malloc(n * sizeof(int)); arr[0] = 1; // 未檢查 NULL配置失敗時解參考 NULL → 崩潰永遠 if (!arr) { handle; }
free(arr); arr[0] = 0;釋放後使用 (Use After Free)free(arr); arr = NULL;
int *arr = malloc(n * sizeof(int)); free(arr); free(arr);重複釋放 (Double Free)釋放後設 NULL,free(NULL) 安全無效
int arr[n]; // VLA (C99)變長陣列在堆疊,大受限、不支援 C11 必選大/未知/長生命週期 → malloc

進階:重新調整大小 — realloc

// 擴充陣列
int *new_arr = realloc(arr, new_n * sizeof(int));
if (!new_arr) { /* 處理失敗,原 arr 仍有效 */ }
arr = new_arr;  // 更新指標 (realloc 可能移動記憶體)

// 縮減陣列 (釋放多餘記憶體)
int *smaller = realloc(arr, smaller_n * sizeof(int));
if (smaller) arr = smaller;  // 縮減通常不失敗,但仍建議檢查

安全模式:void *tmp = realloc(ptr, new_size); if (tmp) ptr = tmp; else handle_error();

記憶體對齊與效能提示

  • malloc 回傳位址滿足**最大基本型別對齊需求** (通常 16 位元組),可直接轉為任何型別指標
  • 大量小配置效能差 → 考慮**記憶體池**、**單次大配置切分**、或 posix_memalign/aligned_alloc (C11)
  • 嵌入式系統無 malloc → 靜態陣列、記憶體池、連結清單

完整模板:可重用的動態陣列結構體

typedef struct {
    int *data;
    size_t size;      // 目前元素數
    size_t capacity;  // 配置容量
} DynArray;

int dyn_init(DynArray *a, size_t init_cap) {
    a->data = malloc(init_cap * sizeof(int));
    if (!a->data) return 0;
    a->size = 0;
    a->capacity = init_cap;
    return 1;
}

int dyn_push(DynArray *a, int val) {
    if (a->size == a->capacity) {
        size_t new_cap = a->capacity ? a->capacity * 2 : 4;
        int *tmp = realloc(a->data, new_cap * sizeof(int));
        if (!tmp) return 0;
        a->data = tmp;
        a->capacity = new_cap;
    }
    a->data[a->size++] = val;
    return 1;
}

void dyn_free(DynArray *a) {
    free(a->data);
    a->data = NULL;
    a->size = a->capacity = 0;
}

總結

  1. malloc(n * sizeof(Type)) 配置
  2. 檢查 NULL
  3. 用 ptr[i] 存取 (指標算術自動處理)
  4. free(ptr); ptr = NULL; 釋放並防懸空
  5. 需變動大小用 realloc (安全模式)

掌握這套流程,動態陣列就不再是難題,而是 C 語言處理不定量資料的利器。

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