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

C語言動態記憶體分配完全指南:malloc、calloc、realloc 與記憶體操作函數詳解

     編輯:關於C語言

動態記憶體分配核心概念

在 C 語言程式設計中,動態記憶體分配是掌握進階開發的關鍵技能。不同於靜態陣列在編譯時期固定大小,動態分配允許程式在執行期根據實際需求向堆區申請記憶體空間,靈活應對資料量不確定的場景。

malloc 函數深度解析

基本語法與特性

void *malloc(size_t size);
  • 參數:以位元組為單位指定申請空間大小
  • 返回值:成功返回分配區塊的起始位址(void*),失敗返回 NULL
  • 特性:不會初始化記憶體內容,殘留資料不可預期

經典使用模式

一維陣列動態分配

int *arr = malloc(sizeof(int) * 10);
if (arr == NULL) { /* 錯誤處理 */ }
for (int i = 0; i < 10; i++) {
    arr[i] = rand() % 91 + 10;  // 產生 10-100 隨機數
}
free(arr);  // 必須釋放,否則記憶體洩漏

二維陣列分配技巧

// 分配 2 行 3 列整數陣列
int (*matrix)[3] = malloc(sizeof(int) * 2 * 3);
matrix[0][0] = 1;
matrix[0][1] = 13;

字串與結構體應用

// 字串複製到堆區
char *str = malloc(12);
strcpy(str, "Hello,Lanou");

// 結構體動態分配
typedef struct {
    char name[20];
    int age;
} Person;

Person *p = malloc(sizeof(Person));
strcpy(p->name, "六娃");
p->age = 34;

其他分配函數比較

函數原型特性適用場景
calloc void *calloc(size_t n, size_t size) 分配 n 個 size 大小區塊,自動歸零 需要初始化為 0 的陣列、結構體
realloc void *realloc(void *ptr, size_t new_size) 調整已分配區塊大小,擴容保留資料,縮容可能截斷 動態陣列擴容、緩衝區調整

記憶體操作三大核心函數

memset - 記憶體填充

void *memset(void *s, int c, size_t n);
  • 將 s 起始的 n 個位元組設為字元 c
  • 常用於結構體/陣列清零:memset(&struct_var, 0, sizeof(struct_var))
  • 適用於堆區與棧區

memcpy - 記憶體複製

void *memcpy(void *dest, const void *src, size_t n);
  • 從 src 複製 n 個位元組到 dest
  • 不檢查重疊,重疊區域請用 memmove
  • 適用於任意類型資料的位元級複製

memcmp - 記憶體比較

int memcmp(const void *s1, const void *s2, size_t n);
  • 比較兩塊記憶體前 n 個位元組
  • 返回值:>0 (s1大)、=0 (相等)、<0 (s1小)
  • 可用於結構體、陣列的快速比較

最佳實踐與避坑指南

  1. 永遠檢查返回值:malloc/calloc/realloc 可能失敗
  2. 配對使用 free:每個分配必須對應一次釋放
  3. 釋放後置空指標:free(ptr); ptr = NULL; 防止野指標
  4. 使用 sizeof 計算大小:避免硬編碼數字,提高可移植性
  5. 注意對齊需求:某些架構要求特定類型對齊

常見錯誤示範

// ❌ 錯誤:未檢查返回值
int *p = malloc(100 * sizeof(int));
p[0] = 10;

// ✅ 正確:完整錯誤處理
int *p = malloc(100 * sizeof(int));
if (!p) {
    fprintf(stderr, "記憶體分配失敗\n");
    exit(EXIT_FAILURE);
}
// 使用 p...
free(p);
p = NULL;
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved