核心知识程序内存五大分区、各分区特性、变量生命周期、动态内存管理、void 指针、C/C 动态内存差异、二维数组模拟、内存风险与扩容一、程序内存五大分区核心概念程序运行时内存划分为 5 个功能区负责存储不同类型数据管理方式、生命周期各不相同。特性代码区存储编译后的程序指令只读程序全程存在。常量区存储字符串常量、const 常量、数字字面量只读不可修改程序全程存在。栈区Stack存储普通局部变量、函数参数、临时变量自动分配、自动释放函数 / 大括号结束作用域仅限当前范围生命周期短。静态全局区静态区存储全局变量、static 全局变量、static 局部变量程序全程存在默认初始化为 0static 局部变量仅初始化一次、值保留。堆区Heap存储手动申请的动态内存手动申请、手动释放生命周期由程序员控制一次性申请内存连续、多次申请不连续。代码示例// 全局变量静态区 int g_num; // 静态全局变量静态区 static int sg_num; ​ void fun() { // 局部变量栈区 int a 10; // 静态局部变量静态区仅初始化一次 static int sl_num 0; // 动态内存堆区 int* p new int; }相似概念比较栈区 vs 堆区栈区自动管理、速度快、空间小、生命周期短。堆区手动管理、速度慢、空间大、生命周期可控。二、变量作用域与生命周期概念作用域指变量有效访问范围生命周期指变量占用内存的时长随内存分区不同而不同。特性局部变量栈区作用域从定义到当前函数 / 大括号结束生命周期同作用域结束即释放未初始化值为随机垃圾值。全局变量静态区作用域整个程序生命周期程序启动到结束默认初始化为 0。静态局部变量静态区作用域仅限定义的函数内生命周期程序全程仅初始化一次值保留。动态变量堆区无固定作用域通过指针访问生命周期从申请到释放不释放则永久占用。代码示例void test() { // 栈区变量作用域仅限test函数 int i 0; // 静态局部变量函数结束不释放下次调用值保留 static int cnt 0; cnt; cout cnt endl; // 多次调用依次输出1、2、3... }三、动态内存管理堆区概念通过 C/C 专用函数 / 运算符手动申请、释放堆内存灵活控制内存使用。同一次申请的内存是连续的不同次不一定。特性1. C 语言malloc/calloc/realloc/free头文件stdlib.hmalloc(字节数)申请指定字节内存不初始化返回void*需强转。calloc(个数, 单字节数)申请 “个数 × 字节数” 内存自动初始化为 0。realloc(旧指针, 新字节数)扩容 / 缩容内存数据保留扩容后地址可能变更。free(指针)释放堆内存释放后指针置空防野指针。2. Cnew/new[]/delete/delete[]new 类型申请单个对象返回对应类型指针。new 类型[n]申请 n 个对象数组。delete 指针释放单个对象。delete[] 指针释放数组必须加 []否则释放不全。3. C vs C 动态内存差异C按字节申请返回void*需手动强转。例如需要10个int型的数组内存直接分配40个字节内存。C按类型申请自动计算大小无需强转语法更安全。例如需要10个int型的数组内存直接分配10个int型内存。代码示例// C语言动态内存 #include stdlib.h //calloc(个数单个的字节数) int* p1 (int*)calloc(10,sizeof(int)); p1[0]; free(p1); p1 NULL; //malloc(总字节数) int* p2 (int*)malloc(10*sizeof(int)); p1[2]; free(p2); p2 NULL; //realloc(起点追加字节数) ​ ​ // C动态内存 int* p3 new int; *p3 0; delete p3; p3 nullptr; ​ int *p4 new int(0); cout*p2endl; delete p4; p4 nullptr; ​ int *p5 new int[5]; p5[3]; delete p5;//错误写法只释放第一个位置 delete[] p5;//自动释放全部 p5 nullptr; ​ // arr[2][3] int **pArr new int*[7]; for(int i0;i7;i){ pArr[i] new int[9]; } pArr[3][4];四、void 指针C 语言核心概念无类型指针可接收任意类型指针但其他类型的指针不能接收void*用于通用内存地址传递。特性可指向任意类型数据不能解引用*p、不能指针偏移无类型大小。不能定义变量无内存大小。用途malloc/calloc/realloc 返回值类型需强转为具体类型后使用。代码示例void* p malloc(4); // *p 10; // 错误不能解引用 int* int_p (int*)p; // 强转后使用 *int_p 10;五、二级指针模拟二维数组堆区概念通过一级指针数组 堆内存灵活模拟二维数组支持动态调整大小。特性原理int** p指向指针数组每个元素p[i]指向一维数组。内存特点每行连续、行与行不连续。释放顺序先释放每行数组再释放指针数组。代码示例// C模拟7行9列二维数组 int** p new int*[7]; // 申请7行指针数组 for (int i 0; i 7; i) { p[i] new int[9]; // 每行申请9列 } // 访问元素 p[0][1] 10; // 释放内存倒序 for (int i 0; i 7; i) { delete[] p[i]; } delete[] p; p NULL;六、动态内存风险必考概念堆内存手动管理易引发严重问题需严格规避。特性内存泄漏申请内存后不释放内存永久占用导致程序卡顿、崩溃、系统性能下降。野指针释放内存后仍通过原指针访问或指针未初始化引发非法内存访问程序崩溃。规避方法申请必释放、释放后置空、不越界访问。代码示例// 内存泄漏示例 void leak() { int* p new int; // 忘记释放内存永久占用 } ​ // 野指针示例 int* p new int; delete p; *p 10; // 错误野指针访问程序崩溃七、动态扩容概念堆内存不足时重新申请更大内存、复制旧数据、释放旧内存实现数组动态增长。特性步骤初始申请→满时扩容如每次 5→申请新内存→复制旧数据→释放旧内存→更新指针。应用动态数组、可变长度数据存储。代码示例int cap 5; // 初始容量 int* arr new int[cap]; int cnt 0; // 数据个数 ​ // 数据满时扩容 if (cnt cap) { cap 5; // 扩容5 int* new_arr new int[cap]; // 复制旧数据 for (int i 0; i cnt; i) { new_arr[i] arr[i]; } delete[] arr; // 释放旧内存 arr new_arr; // 更新指针 }