#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 |
// 擴充陣列
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;
}
malloc(n * sizeof(Type)) 配置ptr[i] 存取 (指標算術自動處理)free(ptr); ptr = NULL; 釋放並防懸空realloc (安全模式)掌握這套流程,動態陣列就不再是難題,而是 C 語言處理不定量資料的利器。