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

C 語言基礎教程(二):指標變數初始化與動態記憶體配置——malloc/free 正確用法

     編輯:C 語言基礎

指標初始化的核心原則:指向有效記憶體

宣告指標 int *p; 只配置指標本身 (4/8 bytes),不配置指向物件的空間。未初始化指標含隨機位址,解參考導致 UB。

錯誤示範 (原教材範例)


int *i;
char *str;
*i = 7899;        /* 災難:寫入隨機位址 */
str = "Good";     /* 合法但指向唯讀區,後續 *str='B' 會崩潰 */

正確模式:malloc 配置 + 指標指向


#include 

int main(void)
{
    int *pi = malloc(sizeof(int));   /* 配置 1 個 int */
    if (!pi) return 1;               /* 檢查配置失敗 */
    *pi = 420;

    char *ps = malloc(20);           /* 配置 20 bytes */
    if (!ps) { free(pi); return 1; }
    strcpy(ps, "Good, Answer!");

    /* 使用結束 */
    free(ps);
    free(pi);
    return 0;
}

模擬陣列:配置連續多個同型別物件


int *pa = malloc(3 * sizeof(int));  /* 3 個 int */
if (!pa) return 1;
pa[0] = 1234;       /* 等價 *(pa+0) */
pa[1] = 4567;       /* 等價 *(pa+1) */
pa[2] = 234;        /* 等價 *(pa+2) */
free(pa);

指標算術與 sizeof 關鍵法則

pa + i 位址 = pa + i * sizeof(*pa) 位元組。
16-bit 環境 sizeof(int)=2 → pa+1 相隔 2 位元組;
32/64-bit 環境 sizeof(int)=4 → pa+1 相隔 4 位元組。

malloc/free 完整契約

函式標頭檔回傳行為
malloc(size_t n)void* (對齊足夠最大型別)配置 n 位元組,內容不定
calloc(n, size)void*配置 n×size 並歸零
realloc(ptr, n)void*調整大小,可能移動位址
free(ptr)void釋放,ptr=NULL 安全無效

常見錯誤模式與修正

  1. 未檢查 NULL:配置失敗回傳 NULL,直接解參考 → Crash。
    修正:if (!p) { handle_error(); }
  2. 重複 free:free(p); free(p); → Heap 損壞。
    修正:free(p); p = NULL;
  3. 釋放非 malloc 位址:free(&local_var); 或 free("literal"); → UB。
    修正:僅釋放 malloc/calloc/realloc 回傳位址。
  4. 釋放後繼續使用:free(p); *p = 0; → Use-after-free。
    修正:釋放即置 NULL。
  5. 型別轉換隱藏錯誤:int *p = malloc(10); (漏 sizeof(int)) 只配 10 bytes。
    修正:int *p = malloc(n * sizeof *p); (推薦寫法,自動適應型別變更)。

進階:自訂配置器模式 (嵌入式/即時系統)


/* 靜態記憶池,避免 heap 碎片與非確定性 */
#define POOL_SIZE 4096
static uint8_t pool[POOL_SIZE];
static size_t offset = 0;

void *pool_alloc(size_t n)
{
    if (offset + n > POOL_SIZE) return NULL;
    void *p = &pool[offset];
    offset += n;
    return p;
}
void pool_reset(void) { offset = 0; }  /* 一次歸還所有 */

現代 C++ 替代方案

  • std::unique_ptr:RAII 自動釋放。
  • std::vector:動態陣列,自動管理記憶體。
  • std::string:字串處理,免手動 malloc/strcpy。

純 C 專案請嚴守「誰配置、誰釋放、配配對、檢查 NULL、釋放置 NULL」六字訣。

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