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

C 語言動態數組構建完整實例:malloc/free 實戰指南

     編輯:關於C語言

C 語言動態數組構建完整實例:malloc/free 實戰指南

動態數組是 C 語言處理「運行時才知道大小」數據的核心技能。本文通過一個完整的交互式程序,演示 `malloc` 分配、`scanf` 填充、`free` 釋放的標準流程,並解析常見錯誤與最佳實踐。

核心代碼實現

#include <stdio.h>
#include <stdlib.h>  // malloc, free 原型在此

int main(void) {
    int len;
    int *arr = NULL;  // 良習:指針初始化為 NULL

    printf("請輸入數組長度: ");
    if (scanf("%d", &len) != 1 || len <= 0) {
        fprintf(stderr, "無效長度\n");
        return 1;
    }

    // 1. 分配內存:類型大小 * 元素個數
    arr = (int *)malloc(len * sizeof(int));
    if (arr == NULL) {  // 必須檢查分配失敗
        perror("malloc 失敗");
        return 1;
    }

    // 2. 使用數組:與靜態數組完全一致
    printf("請輸入 %d 個整數: ", len);
    for (int i = 0; i < len; i++) {
        if (scanf("%d", &arr[i]) != 1) {
            fprintf(stderr, "輸入錯誤\n");
            free(arr);  // 提前退出也要釋放
            return 1;
        }
    }

    // 3. 遍歷輸出
    for (int i = 0; i < len; i++) {
        printf("%d:%d ", i, arr[i]);
    }
    printf("\n");

    // 4. 釋放內存:防止內存洩漏
    free(arr);
    arr = NULL;  // 良習:釋放後置 NULL,防野指針
    return 0;
}

運行示例

$ gcc dynamic_array.c -o dyn -std=c99
$ ./dyn
請輸入數組長度: 5
請輸入 5 個整數: 10 20 30 40 50
0:10 1:20 2:30 3:40 4:50

關鍵知識點深度解析

1. malloc 原型與返回值

void *malloc(size_t size);
// 成功:返回分配內存起始地址(void*,需強轉)
// 失敗:返回 NULL

必須檢查返回值! 忽略檢查是導致段錯誤的首要原因。

2. 內存大小計算

永遠使用 `sizeof(類型) * 個數`,而非硬編碼字節數:

int *p = malloc(n * sizeof(int));      // 正確
double *d = malloc(n * sizeof(double)); // 正確
// 錯誤:int *p = malloc(n * 4); // 假設 int 4 字節,不可移植

3. free 的規則

  • 只能 `free` 由 `malloc`/`calloc`/`realloc` 返回的地址。
  • 同一塊內存只能 `free` 一次(雙重釋放導致堆損壞)。
  • `free(NULL)` 是安全的無操作。
  • 釋放後指針值不變(成為野指針),**建議立即置 NULL**。

4. 靈活擴容:realloc

int *new_arr = realloc(arr, new_len * sizeof(int));
if (new_arr == NULL) {
    // 擴容失敗,原 arr 仍有效,需繼續使用或釋放
} else {
    arr = new_arr; // 成功,更新指針
}

注意:`realloc` 可能移動內存塊,舊指針失效,必須用返回值更新。

常見錯誤總結

錯誤代碼後果修正
`int *p; p[0]=1;`野指針寫入,崩潰先 malloc
`malloc(n*4);`不可移植`malloc(n*sizeof(int))`
不檢查 malloc 返回值後續解引用 NULL 崩潰判空處理
忘記 free內存洩漏配對 free
free 後繼續使用指針Use-after-free,未定義行為free 後置 NULL

進階:封裝動態數組結構體

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

void dyn_init(DynArray *a) { a->data=NULL; a->size=0; a->capacity=0; }
void dyn_push(DynArray *a, int val) {
    if (a->size == a->capacity) {
        size_t new_cap = a->capacity ? a->capacity*2 : 4;
        int *p = realloc(a->data, new_cap*sizeof(int));
        if (!p) return; // 錯誤處理省略
        a->data = p; a->capacity = new_cap;
    }
    a->data[a->size++] = val;
}
void dyn_free(DynArray *a) { free(a->data); dyn_init(a); }

總結

動態數組 = `malloc` 分配 + 下標訪問 + `free` 釋放。掌握「檢查返回值、正確計算大小、配對釋放、釋放後置 NULL」四大鐵律,即可安全高效地在 C 語言中處理任意大小的數據集合。

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