内存管理是C语言编程的核心技能,掌握内存管理对于编写高效、稳定的程序至关重要。东巴文(db-w.cn) 将带你深入理解内存管理的原理与实践。
💡 东巴文观点:C语言赋予了程序员对内存的直接控制权,这是优势也是责任。正确的内存管理是程序稳定运行的基础。
#include <stdio.h>
#include <stdlib.h>
int globalVar = 100; // 全局区(已初始化)
int globalUninit; // 全局区(未初始化)
const int constVar = 200; // 常量区
void memoryLayout() {
printf("=== 东巴文内存分区模型 ===\n\n");
int localVar = 10; // 栈区
static int staticVar = 20; // 全局区(静态)
int *heapVar = (int *)malloc(sizeof(int)); // 堆区
*heapVar = 30;
printf("栈区变量:\n");
printf(" localVar地址:%p\n", &localVar);
printf("\n堆区变量:\n");
printf(" heapVar地址:%p\n", heapVar);
printf("\n全局区变量:\n");
printf(" globalVar地址:%p\n", &globalVar);
printf(" globalUninit地址:%p\n", &globalUninit);
printf(" staticVar地址:%p\n", &staticVar);
printf("\n常量区变量:\n");
printf(" constVar地址:%p\n", &constVar);
printf("\n代码区:\n");
printf(" memoryLayout函数地址:%p\n", memoryLayout);
free(heapVar);
}
int main() {
memoryLayout();
return 0;
}
东巴文内存分区表:
| 区域 | 内容 | 特点 | 生命周期 |
|---|---|---|---|
| 栈区 | 局部变量、函数参数 | 自动管理,向下生长 | 函数调用期间 |
| 堆区 | 动态分配的内存 | 手动管理,向上生长 | 程序员控制 |
| 全局区 | 全局变量、静态变量 | 程序启动时分配 | 程序运行期间 |
| 常量区 | 常量、字符串字面量 | 只读 | 程序运行期间 |
| 代码区 | 程序代码 | 只读 | 程序运行期间 |
#include <stdio.h>
void stackDemo() {
printf("=== 东巴文栈区演示 ===\n\n");
int a = 10;
int b = 20;
int c = 30;
printf("栈区变量地址(向下生长):\n");
printf(" &a = %p\n", &a);
printf(" &b = %p\n", &b);
printf(" &c = %p\n", &c);
printf("\n栈区特点:\n");
printf(" - 自动分配和释放\n");
printf(" - 空间有限\n");
printf(" - 后进先出\n");
}
int main() {
stackDemo();
return 0;
}
#include <stdio.h>
#include <stdlib.h>
int main() {
printf("=== 东巴文堆区演示 ===\n\n");
int *ptr1 = (int *)malloc(sizeof(int));
int *ptr2 = (int *)malloc(sizeof(int));
int *ptr3 = (int *)malloc(sizeof(int));
printf("堆区变量地址(向上生长):\n");
printf(" ptr1 = %p\n", ptr1);
printf(" ptr2 = %p\n", ptr2);
printf(" ptr3 = %p\n", ptr3);
printf("\n堆区特点:\n");
printf(" - 手动分配和释放\n");
printf(" - 空间较大\n");
printf(" - 灵活控制\n");
// 释放内存
free(ptr1);
free(ptr2);
free(ptr3);
return 0;
}
#include <stdio.h>
// 全局变量
int globalInit = 100; // 已初始化全局区
int globalUninit; // 未初始化全局区
// 静态全局变量
static int staticGlobal = 200;
void globalDemo() {
printf("=== 东巴文全局区演示 ===\n\n");
// 静态局部变量
static int staticLocal = 300;
printf("全局区变量地址:\n");
printf(" globalInit = %p\n", &globalInit);
printf(" globalUninit = %p\n", &globalUninit);
printf(" staticGlobal = %p\n", &staticGlobal);
printf(" staticLocal = %p\n", &staticLocal);
printf("\n全局区特点:\n");
printf(" - 程序启动时分配\n");
printf(" - 程序结束时释放\n");
printf(" - 默认初始化为0\n");
}
int main() {
globalDemo();
return 0;
}
#include <stdio.h>
#include <stdlib.h>
int main() {
printf("=== 东巴文malloc函数 ===\n\n");
// 分配单个变量
int *ptr = (int *)malloc(sizeof(int));
if (ptr != NULL) {
*ptr = 100;
printf("分配的值:*ptr = %d\n", *ptr);
printf("分配的地址:ptr = %p\n", ptr);
free(ptr);
ptr = NULL;
}
// 分配数组
int size = 5;
int *arr = (int *)malloc(size * sizeof(int));
if (arr != NULL) {
printf("\n分配数组:\n");
for (int i = 0; i < size; i++) {
arr[i] = i + 1;
printf("arr[%d] = %d\n", i, arr[i]);
}
free(arr);
arr = NULL;
}
return 0;
}
东巴文说明:
malloc 在堆区分配内存void* 指针NULL#include <stdio.h>
#include <stdlib.h>
int main() {
printf("=== 东巴文calloc函数 ===\n\n");
int size = 5;
int *arr = (int *)calloc(size, sizeof(int));
if (arr != NULL) {
printf("calloc分配的数组(已初始化为0):\n");
for (int i = 0; i < size; i++) {
printf("arr[%d] = %d\n", i, arr[i]);
}
free(arr);
arr = NULL;
}
return 0;
}
东巴文说明:
calloc 分配并初始化为0#include <stdio.h>
#include <stdlib.h>
int main() {
printf("=== 东巴文realloc函数 ===\n\n");
// 初始分配
int size = 5;
int *arr = (int *)malloc(size * sizeof(int));
if (arr != NULL) {
printf("初始分配:\n");
for (int i = 0; i < size; i++) {
arr[i] = i + 1;
printf("arr[%d] = %d\n", i, arr[i]);
}
// 扩展内存
int newSize = 10;
int *newArr = (int *)realloc(arr, newSize * sizeof(int));
if (newArr != NULL) {
arr = newArr;
printf("\n扩展后:\n");
for (int i = 0; i < newSize; i++) {
printf("arr[%d] = %d\n", i, arr[i]);
}
}
free(arr);
arr = NULL;
}
return 0;
}
东巴文说明:
realloc 调整已分配内存的大小NULL,原内存不变#include <stdio.h>
#include <stdlib.h>
int main() {
printf("=== 东巴文free函数 ===\n\n");
int *ptr = (int *)malloc(sizeof(int));
if (ptr != NULL) {
*ptr = 100;
printf("分配的值:*ptr = %d\n", *ptr);
// 释放内存
free(ptr);
printf("内存已释放\n");
// ✅ 推荐:释放后置NULL
ptr = NULL;
// ❌ 错误:释放后访问
// printf("*ptr = %d\n", *ptr); // 悬空指针
}
return 0;
}
东巴文说明:
free 释放动态分配的内存NULL#include <stdio.h>
#include <stdlib.h>
void memoryLeakDemo() {
printf("=== 东巴文内存泄漏演示 ===\n\n");
// ❌ 内存泄漏:忘记释放
int *ptr1 = (int *)malloc(sizeof(int));
*ptr1 = 100;
printf("ptr1 = %d\n", *ptr1);
// 忘记 free(ptr1);
// ❌ 内存泄漏:指针丢失
int *ptr2 = (int *)malloc(sizeof(int));
*ptr2 = 200;
printf("ptr2 = %d\n", *ptr2);
ptr2 = (int *)malloc(sizeof(int)); // 原内存丢失
// 忘记 free(ptr2);
// ❌ 内存泄漏:重复分配
int *ptr3 = (int *)malloc(sizeof(int));
ptr3 = (int *)malloc(sizeof(int)); // 原内存丢失
// 忘记 free(ptr3);
printf("\n以上都是内存泄漏的例子\n");
}
int main() {
memoryLeakDemo();
return 0;
}
#include <stdio.h>
#include <stdlib.h>
void noMemoryLeak() {
printf("=== 东巴文防止内存泄漏 ===\n\n");
// ✅ 正确:及时释放
int *ptr1 = (int *)malloc(sizeof(int));
if (ptr1 != NULL) {
*ptr1 = 100;
printf("ptr1 = %d\n", *ptr1);
free(ptr1);
ptr1 = NULL;
}
// ✅ 正确:先释放再重新分配
int *ptr2 = (int *)malloc(sizeof(int));
if (ptr2 != NULL) {
*ptr2 = 200;
printf("ptr2 = %d\n", *ptr2);
free(ptr2);
ptr2 = NULL;
ptr2 = (int *)malloc(sizeof(int));
if (ptr2 != NULL) {
*ptr2 = 300;
printf("ptr2 = %d\n", *ptr2);
free(ptr2);
ptr2 = NULL;
}
}
printf("\n正确管理内存\n");
}
int main() {
noMemoryLeak();
return 0;
}
#include <stdio.h>
#include <stdlib.h>
int main() {
printf("=== 东巴文悬空指针 ===\n\n");
int *ptr = (int *)malloc(sizeof(int));
*ptr = 100;
printf("释放前:*ptr = %d\n", *ptr);
free(ptr);
// ❌ 错误:悬空指针
// printf("释放后:*ptr = %d\n", *ptr);
// ✅ 正确:置NULL
ptr = NULL;
printf("正确处理悬空指针\n");
return 0;
}
#include <stdio.h>
#include <stdlib.h>
int main() {
printf("=== 东巴文重复释放 ===\n\n");
int *ptr = (int *)malloc(sizeof(int));
*ptr = 100;
printf("ptr = %d\n", *ptr);
free(ptr);
// ❌ 错误:重复释放
// free(ptr);
// ✅ 正确:置NULL后可以安全释放
ptr = NULL;
// free(ptr); // 释放NULL是安全的
printf("正确处理重复释放\n");
return 0;
}
#include <stdio.h>
#include <stdlib.h>
int main() {
printf("=== 东巴文越界访问 ===\n\n");
int size = 5;
int *arr = (int *)malloc(size * sizeof(int));
if (arr != NULL) {
// 正确访问
for (int i = 0; i < size; i++) {
arr[i] = i + 1;
}
// ❌ 错误:越界访问
// arr[5] = 100; // 越界
// arr[-1] = 100; // 越界
printf("正确访问数组\n");
free(arr);
arr = NULL;
}
return 0;
}
#include <stdio.h>
#include <stdlib.h>
int main() {
printf("=== 东巴文未检查返回值 ===\n\n");
// ❌ 错误:未检查返回值
// int *ptr = (int *)malloc(1000000000000);
// *ptr = 100; // 可能崩溃
// ✅ 正确:检查返回值
int *ptr = (int *)malloc(sizeof(int));
if (ptr != NULL) {
*ptr = 100;
printf("ptr = %d\n", *ptr);
free(ptr);
ptr = NULL;
} else {
printf("内存分配失败\n");
}
return 0;
}
#include <stdio.h>
#include <stdlib.h>
void processData() {
int *data = (int *)malloc(100 * sizeof(int));
if (data != NULL) {
// 使用数据...
// ✅ 正确:及时释放
free(data);
data = NULL;
}
}
int main() {
printf("=== 东巴文及时释放内存 ===\n\n");
processData();
printf("内存已正确释放\n");
return 0;
}
#include <stdio.h>
#include <stdlib.h>
int main() {
printf("=== 东巴文使用NULL检查 ===\n\n");
int *ptr = (int *)malloc(sizeof(int));
// ✅ 正确:检查NULL
if (ptr != NULL) {
*ptr = 100;
printf("ptr = %d\n", *ptr);
free(ptr);
ptr = NULL;
} else {
printf("内存分配失败\n");
}
return 0;
}
#include <stdio.h>
#include <stdlib.h>
int main() {
printf("=== 东巴文配对使用malloc和free ===\n\n");
int *ptr1 = (int *)malloc(sizeof(int));
int *ptr2 = (int *)calloc(5, sizeof(int));
int *ptr3 = (int *)realloc(NULL, sizeof(int));
// ✅ 正确:每个malloc对应一个free
free(ptr1);
free(ptr2);
free(ptr3);
ptr1 = NULL;
ptr2 = NULL;
ptr3 = NULL;
printf("内存正确配对释放\n");
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#define POOL_SIZE 100
typedef struct {
int data[POOL_SIZE];
int used;
} MemoryPool;
void initPool(MemoryPool *pool) {
pool->used = 0;
}
int *allocateFromPool(MemoryPool *pool) {
if (pool->used < POOL_SIZE) {
return &pool->data[pool->used++];
}
return NULL;
}
int main() {
printf("=== 东巴文使用内存池 ===\n\n");
MemoryPool pool;
initPool(&pool);
// 从内存池分配
int *ptr1 = allocateFromPool(&pool);
int *ptr2 = allocateFromPool(&pool);
if (ptr1 != NULL) *ptr1 = 100;
if (ptr2 != NULL) *ptr2 = 200;
printf("ptr1 = %d\n", *ptr1);
printf("ptr2 = %d\n", *ptr2);
printf("\n内存池优势:\n");
printf(" - 减少内存碎片\n");
printf(" - 提高分配效率\n");
printf(" - 便于管理\n");
return 0;
}
完成本章学习后,请确认:
掌握内存管理后,你可以继续学习:
如果遇到问题,欢迎访问 东巴文(db-w.cn) 获取帮助!
东巴文(db-w.cn) - 让编程学习更简单
🎯 东巴文内存管理提示:正确的内存管理是程序稳定运行的基础。在 db-w.cn,我们会通过大量实例帮你掌握内存管理!