C语言动态内存分配 学习笔记

C语言动态内存分配 学习笔记 职坐标学习 C语言动态内存分配 学习笔记一、动态内存的概念与分类1. 为什么需要动态内存栈内存的局限大小固定定义变量或数组时空间大小在编译时就已确定如int arr[10]。生命周期受限函数调用结束后栈上的局部变量会自动释放。动态内存的优势按需分配在程序运行时根据需要申请内存大小可变。手动管理生命周期由程序员控制直到显式释放。灵活性强适合处理大小不确定的数据如用户输入、文件读取。2. 核心类比租赁仓库静态内存 (栈)就像买了一个固定大小的仓库无论用不用空间都占着。动态内存 (堆)就像租仓库需要多少租多少用完就退租。malloc 去仓库管理员那里申请租用。free 退租归还。内存泄漏 忘记free永远占着仓库不退。双重释放 同一个仓库退了两次。3. 内存基础内存 (主存储器)CPU可以直接访问的临时存储部件读写速度快但断电后数据丢失。大小端序多字节数据在内存中的存储顺序。大端序高位字节存在低地址人类阅读习惯网络传输标准。小端序低位字节存在低地址Intel x86架构运算效率高。二、动态内存管理函数1. malloc 和 freemalloc(Memory Allocation)原型void* malloc(size_t size);作用在堆区分配指定字节数的内存。返回值成功返回void*指针需强制类型转换失败返回NULL。特点不初始化内存中是随机的“垃圾值”。free原型void free(void* ptr);作用释放ptr指向的内存块。注意释放后应将指针置为NULL防止野指针。代码示例malloc 与 free1#include stdio.h 2#include stdlib.h 3 4int main() { 5 // 1. 分配内存 (5个int的大小) 6 int* arr (int*)malloc(5 * sizeof(int)); 7 8 // 2. 检查是否分配成功 9 if (arr NULL) { 10 printf(内存分配失败!\n); 11 return 1; 12 } 13 14 // 3. 使用内存 15 for (int i 0; i 5; i) { 16 arr[i] i * 10; 17 } 18 19 // 4. 释放内存 20 free(arr); 21 arr NULL; // 避免野指针 22 23 return 0; 24}2. calloc原型void* calloc(size_t num, size_t size);作用分配num个大小为size的连续内存块。特点自动将所有字节初始化为 0。类比预订并打扫干净的酒店房间入住即用。对比malloc vs calloc特性malloc(size)calloc(num, size)初始化未初始化 (随机值)初始化为 0参数总字节数元素个数, 单个元素大小速度稍快稍慢 (需清零)场景后续会覆盖数据需要初始值为0 (如计数器、数组)3. memset (辅助初始化)原型void* memset(void* ptr, int value, size_t num);作用将ptr指向的内存块的前num个字节设置为value。注意按字节填充。设置int数组为1时每个字节变为0x01结果不是1而是16843001(0x01010101)。通常只用于初始化为0或-1。4. realloc原型void* realloc(void* ptr, size_t size);作用调整已分配内存块的大小扩大或缩小。返回值返回新内存块的指针地址可能改变。机制原地扩容如果原空间后面有足够的空闲空间直接扩大。搬家扩容如果原空间不够会分配一块新的大内存将旧数据拷贝过去释放旧内存返回新地址。类比搬家换大房子。房东系统帮你把旧家具数据搬到新房子然后退掉旧房子。代码示例realloc 扩容1// 假设 arr 是 malloc 分配的 2int* newArr (int*)realloc(arr, 10 * sizeof(int)); 3if (newArr ! NULL) { 4 arr newArr; // 更新指针 5 // 现在可以使用 arr[5] 到 arr[9] 6}三、综合案例动态数组 (Dynamic Array)这是一个模拟 Cstd::vector的简易实现展示了动态内存的增删改查 (CRUD) 和自动扩容机制。1. 数据结构设计1typedef struct { 2 int* data; // 指向堆内存的指针 3 int size; // 当前元素个数 4 int capacity; // 当前最大容量 5} DynamicArray; 6 7 8x2. 核心功能实现创建与销毁createDynamicArray(int cap)分配结构体和初始数组内存。freeArray(DynamicArray* arr)先free(arr-data)再free(arr)。自动扩容 (expandCapacity)当size capacity时触发。使用realloc将容量翻倍 (capacity * 2)。更新data指针和capacity。尾插法 (append)检查是否需要扩容。data[size] value然后size。指定位置插入 (insertAt)检查索引合法性。检查是否需要扩容。数据搬移从后往前将index及之后的元素向后移动一位。插入新值size。删除元素 (deleteAt)保存被删除的值。数据搬移从前往后将index之后的元素向前覆盖。size--。3. 业务逻辑流程图 (Mermaid)graph TDA[开始: append(arr, value)] -- B{数组已满?}B -- 是 -- C[调用 expandCapacity]C -- D{扩容成功?}D -- 否 -- E[返回失败]D -- 是 -- F[写入数据]B -- 否 -- FF -- G[size]G -- H[结束: 返回成功]四、工程化实战AI 赋能的学生管理系统本节介绍了如何利用 AI 辅助进行企业级软件开发从需求分析到技术设计的完整流程。1. 需求分析阶段 (SRS)目标明确“做什么”。SMART 原则Specific(具体的)开发学生管理系统。Measurable(可衡量的)支持 1000 名学生。Achievable(可实现的)C语言 动态数组。Relevant(相关的)解决教务管理痛点。Time-bound(有时限的)1天内完成。产出物《需求分析报告.md》包含功能列表、优先级、IPO分析。2. 系统设计阶段 (Technical Spec)目标明确“怎么做”。核心内容架构设计分层架构表现层、业务层、数据层。接口设计定义函数原型、参数、返回值、错误码。数据设计定义struct结构体。产出物《技术规格说明书.md》。3. AI 技能 (Skill) 的应用需求分析 Skill根据自然语言描述自动生成 SRS 文档。技术设计 Skill读取 SRS生成 Technical Spec包含 Mermaid 架构图和接口定义。开发流程用户输入需求 - AI 生成 SRS。用户确认 SRS - AI 生成 Technical Spec。程序员根据 Spec 编码。4. 模块化设计示例主程序模块 (main.c)负责菜单显示、用户交互。学生管理模块 (student_manager.c)负责 CRUD 逻辑、动态数组管理。工具模块 (utils.c)负责输入验证、字符串处理。五、核心知识点速记卡知识点关键总结malloc分配内存不初始化返回void*失败返回NULL。calloc分配内存自动清零参数是 (数量, 大小)。realloc调整内存大小可能移动地址失败返回NULL(原内存不变)。free释放内存必须配对使用释放后置NULL防野指针。内存泄漏malloc了但没free导致内存一直被占用。野指针指针指向的内存已被释放但指针未置空。SRS需求规格说明书解决“做什么”的问题。Technical Spec技术规格说明书解决“怎么做”的问题架构、接口、数据。学习建议检查 NULL每次malloc/calloc/realloc后必须检查返回值是否为NULL。配对原则malloc和free必须成对出现确保没有内存泄漏。理解 reallocrealloc返回的新地址可能与旧地址不同务必用新地址更新指针。避免野指针free(p)后立即执行p NULL。工程思维学习使用 SRS 和 Technical Spec 规范开发流程这是从“写代码”到“做工程”的跨越。