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

C 語言指針動態分配實戰(十一):malloc 正確用法、指針算術陷阱與多元素分配

     編輯:關於C語言

前言

未初始化的指針指向隨機地址,直接使用會破壞系統數據甚至導致死機。本文以 Turbo C 2.0 為背景,詳細演示 **malloc 動態分配正確模式**、**指針算術與類型大小的關係**、**多元素連續分配** 實戰,並揭示 *(p+1) ≠ 下一字節的核心誤區。

一、錯誤代碼剖析

/* 危險:野指針 */
main() {
    int *i;
    char *str;
    *i = 420;           // 崩潰/亂寫
    str = "Good";       // 僅修改指針指向常量區,未分配可寫空間
}

二、正確模式:malloc + 強制轉換 + 解引用

#include   /* 或  */

main() {
    int *i;
    char *str;

    /* 分配 1 個 int (2 字節) */
    i = (int*)malloc(sizeof(int));
    if (!i) exit(1);      // 必檢查 NULL
    *i = 420;             // 正確寫入

    /* 分配 20 字節字符緩衝區 */
    str = (char*)malloc(20);
    if (!str) exit(1);
    strcpy(str, "Good, Answer!");  // 安全拷貝

    /* 使用完畢必須釋放 */
    free(i);
    free(str);
}

三、分配多個同類型元素:連續塊 + 指針算術

#include 

main() {
    int *a;
    a = (int*)malloc(3 * sizeof(int));  // 分配 3 個 int (6 字節)
    if (!a) exit(1);

    *a = 1234;          // a[0]
    *(a + 1) = 4567;    // a[1]
    *(a + 2) = 234;     // a[2]

    /* 等價下標寫法 */
    a[0] = 1234;
    a[1] = 4567;
    a[2] = 234;

    free(a);
}

四、核心誤區:*(p+1) 不是下一字節!

指針算術以「所指類型大小」為單位縮放,而非位元組。

指針類型sizeofp+1 位移位元組等價下標
int *22p[1]
char *11p[1]
double *88p[1]
struct Stu *結構大小結構大小p[1]

因此:int *a; *(a+1) = 4567 寫入的是**第 2 個 int (偏移 2 字節)**,而非第 2 字節。

五、malloc 返回值檢查:生死線

  • malloc 失敗返回 NULL (0)。
  • **必須**檢查:if (!ptr) { fprintf(stderr, "OOM\n"); exit(1); }。
  • 未檢查直接解引用 NULL → 段錯誤/崩潰。

六、完整生命週期模板

/* 分配 → 檢查 → 使用 → 釋放 → 置 NULL */
int *p = (int*)malloc(N * sizeof(int));
if (!p) handle_oom();

for (int i = 0; i < N; i++) p[i] = compute(i);
process(p, N);

free(p);
p = NULL;  // 防止懸空指針二次 free / 使用

七、Turbo C 具體細節

  • 頭文件:alloc.h (Borland 專用) 或 stdlib.h (ANSI)。
  • 內存模式影響指針大小:Small (近指針 2B) / Large (遠指針 4B)。malloc 返回對應模式指針。
  • farcalloc/farmalloc 可跨 64KB 段分配 (大模式專用)。

八、常見錯誤速查

錯誤後果修正
malloc(sizeof(p))分配指針大小而非目標類型malloc(sizeof(*p)) 或 malloc(sizeof(int))
忘記 free記憶體洩漏嚴格配對 malloc/free
free(p); free(p);二次釋放 → 堆損壞free(p); p = NULL;
釋放非 malloc 記憶體未定義行為僅釋放 malloc/calloc/realloc 返回指針
指針算術按字節計算訪問錯誤元素/越界牢記:按 sizeof(*p) 縮放

總結

malloc + 指針算術 = C 語言**動態記憶體管理**的核心原語。三大鐵律:**檢查 NULL、按類型縮放算術、用完即 free 置 NULL**。掌握此道,即可構建動態陣列、鏈表、樹、圖、哈希表等所有高級數據結構的存儲骨架。

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