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

C 語言記憶體分配陷阱:棧與堆的關鍵差異解析

     編輯:關於C語言

前言:一次面試引發的深思

前陣子抱著「打醬油」的心態參加了學校某社團的幹部面試,沒想到卻被幾個看似簡單的 C 語言問題卡住了。面試結束後,我花了一整天時間徹底搞懂了這些問題,這才發現:平時多去面試還真有好處,至少能精準定位自己的技術盲區。今天就來深入剖析其中一道關於記憶體分配的經典面試題。

案例一:區域變數陷阱

請先看這段代碼:

void allocmem(char **p)
{
    char r[10] = {1};
    *p = r;
}

int main()
{
    int i;
    char *m = NULL;
    allocmem(&m);
    if (m)
    {
        for (i = 0; i < 10; i++)
            printf("m[%d] = %d\n", i, m[i]);
    }
    else
    {
        printf("alloc mem failed\n");
    }
    return 0;
}

運行結果顯示數據已經損壞,出現亂碼。為什麼?因為 r[10] 是 區域變數(棧上分配),函數 allocmem 返回後,棧幀銷毀,記憶體被系統回收,指標 m 變成了懸空指標,指向的內容不可預測。

案例二:動態分配的正確姿勢

再看這段代碼:

void allocmem(char **p)
{
    *p = malloc(10);
    memset(*p, 1, 10);
}

int main()
{
    int i;
    char *m = NULL;
    allocmem(&m);
    if (m)
    {
        for (i = 0; i < 10; i++)
            printf("m[%d] = %d\n", i, m[i]);
    }
    else
    {
        printf("alloc mem failed\n");
    }
    return 0;
}

這次輸出正常,全是 1。關鍵差異在於 malloc 在 堆上分配記憶體,函數結束不會自動釋放,必須由程式設計師手動 free。

核心總結:棧 vs 堆

特性棧堆
分配方式區域變數、自動分配malloc/free、手動管理
生命週期隨函數調用結束自動釋放需手動釋放,否則洩漏
空間大小較小(通常 MB 級)較大(受限於虛擬記憶體)
分配速度極快(指針移動)較慢(需尋找合適塊)

避坑指南: 永遠不要返回區域變數的地址!若需跨函數使用記憶體,請使用動態分配(malloc/new)或靜態/全域變數。

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