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

C/C++ 內存分配全景解析:五大區域、棧堆差異、實例圖解

     編輯:C++ 入門

一、C/C++ 內存五大存儲區

區域存儲內容管理方式生命週期
棧局部變量、函數參數、返回地址編譯器自動分配/釋放函數結束自動銷毀
堆動態分配內存(new/malloc)程序員手動管理手動釋放或程序結束由 OS 回收
全局/靜態區全局變量、靜態變量(static)編譯時分配程序全生命週期
常量區字符串字面值、const 修飾的常量編譯時分配程序全生命週期,通常只讀
代碼區二進制機器指令編譯時生成程序全生命週期,只讀

二、棧與堆核心差異

維度棧堆
提供者系統(CPU 指令支持)C/C++ 運行時庫
效率極高(指針移動)較低(鏈表查找/合併)
靈活性固定大小、LIFO任意大小、任意順序分配釋放
碎片無有(外部碎片)
生長方向向下(高地址→低地址)向上(低地址→高地址)
唯一性每線程一個進程可有多個堆

三、實例代碼註解

int a = 0;           // 全局初始化區
char *p1;            // 全局未初始化區 (BSS)

int main() {
    int b;           // 棧
    char s[] = "abc"; // 棧 (數組內容拷貝自常量區)
    char *p2;        // 棟 (指針變量本身)
    char *p3 = "123456"; // "123456\0" 在常量區,p3 在棧
    static int c = 0; // 全局/靜態初始化區
    
    p1 = new char[10]; // 堆分配 10 字節
    p2 = new char[20]; // 堆分配 20 字節
    strcpy(p1, "123456"); // 字符串拷貝到堆,"123456\0" 仍在常量區
    // 編譯器可能優化:p1 和 p3 指向同一常量區地址
}

四、常見誤區與最佳實踐

  • 棧溢出:避免大數組/遞歸過深放在棧上
  • 內存洩漏:堆內存必須配對 delete/free
  • 懸空指針:釋放後置 nullptr
  • 野指針:指針聲明時初始化為 nullptr
  • 全局變量濫用:增加耦合、難維護、佔用靜態區,慎用

五、進階:內存對齊與結構體佈局

結構體成員按聲明順序排列,編譯器插入填充字節滿足對齊要求(通常為成員大小或編譯器默認對齊數)。可用 #pragma pack(n) 或屬性 __attribute__((packed)) 控制。

總結

理解五大內存區特性,掌握棧堆差異,是寫出高效、穩健 C/C++ 代碼的基礎。實戰中:優先用棧(RAII、智能指針)、謹慎用堆、少用全局、常量區只讀。

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