动态内存分配是C语言编程的核心技能,它允许程序在运行时根据需要分配内存。东巴文(db-w.cn) 将带你深入理解动态内存分配的原理与实践。
💡 东巴文观点:动态内存分配赋予了程序灵活性,但也带来了内存管理的责任。正确的内存管理是程序稳定运行的基础。
#include <stdio.h>
void staticAllocationLimitation() {
printf("=== 东巴文静态分配的局限性 ===\n\n");
// 静态分配:编译时确定大小
int staticArray[100]; // 固定大小
printf("静态分配的特点:\n");
printf(" 1. 编译时确定大小\n");
printf(" 2. 大小固定,不能改变\n");
printf(" 3. 可能造成内存浪费\n");
printf(" 4. 可能造成内存不足\n");
printf("\n问题:\n");
printf(" - 如果需要1000个元素?\n");
printf(" - 如果只需要10个元素?\n");
printf(" - 如果运行时才知道需要多少?\n");
}
int main() {
staticAllocationLimitation();
return 0;
}
#include <stdio.h>
#include <stdlib.h>
void dynamicAllocationAdvantage() {
printf("=== 东巴文动态分配的优势 ===\n\n");
int size;
printf("请输入数组大小:");
scanf("%d", &size);
// 动态分配:运行时确定大小
int *dynamicArray = (int *)malloc(size * sizeof(int));
if (dynamicArray != NULL) {
printf("\n动态分配成功!\n");
printf(" 分配的元素个数:%d\n", size);
printf(" 分配的字节数:%zu\n", size * sizeof(int));
// 使用数组...
free(dynamicArray);
} else {
printf("内存分配失败!\n");
}
}
int main() {
dynamicAllocationAdvantage();
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;
} else {
printf("内存分配失败!\n");
}
return 0;
}
东巴文说明:
malloc 在堆区分配内存void* 指针,失败返回 NULL#include <stdio.h>
#include <stdlib.h>
int main() {
printf("=== 东巴文malloc分配数组 ===\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;
}
// 输出
printf("数组内容:\n");
for (int i = 0; i < size; i++) {
printf("arr[%d] = %d\n", i, arr[i]);
}
free(arr);
arr = NULL;
}
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char name[50];
int age;
float score;
} Student;
int main() {
printf("=== 东巴文malloc分配结构体 ===\n\n");
// 分配单个结构体
Student *stu = (Student *)malloc(sizeof(Student));
if (stu != NULL) {
strcpy(stu->name, "东巴文");
stu->age = 20;
stu->score = 95.5;
printf("学生信息:\n");
printf(" 姓名:%s\n", stu->name);
printf(" 年龄:%d\n", stu->age);
printf(" 成绩:%.1f\n", stu->score);
free(stu);
stu = NULL;
}
return 0;
}
#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 分配并初始化为0void* 指针,失败返回 NULL#include <stdio.h>
#include <stdlib.h>
int main() {
printf("=== 东巴文malloc vs calloc ===\n\n");
int size = 5;
// malloc:未初始化
int *arr1 = (int *)malloc(size * sizeof(int));
printf("malloc分配(未初始化):\n");
for (int i = 0; i < size; i++) {
printf("arr1[%d] = %d\n", i, arr1[i]);
}
// calloc:初始化为0
int *arr2 = (int *)calloc(size, sizeof(int));
printf("\ncalloc分配(初始化为0):\n");
for (int i = 0; i < size; i++) {
printf("arr2[%d] = %d\n", i, arr2[i]);
}
free(arr1);
free(arr2);
return 0;
}
东巴文对比表:
| 特性 | malloc | 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) {
// 初始化
for (int i = 0; i < size; i++) {
arr[i] = i + 1;
}
printf("初始分配:\n");
for (int i = 0; i < size; i++) {
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("=== 东巴文realloc的特殊用法 ===\n\n");
// realloc(NULL, size) 等价于 malloc(size)
int *ptr1 = (int *)realloc(NULL, sizeof(int));
*ptr1 = 100;
printf("realloc(NULL, size):*ptr1 = %d\n", *ptr1);
// realloc(ptr, 0) 等价于 free(ptr)
int *ptr2 = (int *)malloc(sizeof(int));
*ptr2 = 200;
printf("realloc(ptr, 0):释放内存\n");
realloc(ptr2, 0);
free(ptr1);
return 0;
}
#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;
}
return 0;
}
东巴文说明:
free 释放动态分配的内存NULLNULL 是安全的#include <stdio.h>
#include <stdlib.h>
int main() {
printf("=== 东巴文free的常见错误 ===\n\n");
int *ptr = (int *)malloc(sizeof(int));
*ptr = 100;
// ❌ 错误1:重复释放
free(ptr);
// free(ptr); // 错误:重复释放
// ✅ 正确:释放后置NULL
ptr = NULL;
free(ptr); // 释放NULL是安全的
// ❌ 错误2:释放非动态分配的内存
int localVar = 10;
// free(&localVar); // 错误:释放栈区内存
// ❌ 错误3:释放部分内存
int *arr = (int *)malloc(10 * sizeof(int));
// free(arr + 5); // 错误:释放部分内存
free(arr); // 正确:释放整个内存
printf("正确使用free\n");
return 0;
}
#include <stdio.h>
#include <stdlib.h>
int main() {
printf("=== 东巴文一维动态数组 ===\n\n");
int size;
printf("请输入数组大小:");
scanf("%d", &size);
int *arr = (int *)malloc(size * sizeof(int));
if (arr != NULL) {
// 初始化
for (int i = 0; i < size; i++) {
arr[i] = i + 1;
}
// 输出
printf("数组内容:\n");
for (int i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");
free(arr);
}
return 0;
}
#include <stdio.h>
#include <stdlib.h>
int main() {
printf("=== 东巴文二维动态数组 ===\n\n");
int rows = 3, cols = 4;
// 分配指针数组
int **matrix = (int **)malloc(rows * sizeof(int *));
if (matrix != NULL) {
// 为每一行分配内存
for (int i = 0; i < rows; i++) {
matrix[i] = (int *)malloc(cols * sizeof(int));
}
// 初始化
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
matrix[i][j] = i * cols + j + 1;
}
}
// 输出
printf("二维数组:\n");
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
printf("%2d ", matrix[i][j]);
}
printf("\n");
}
// 释放内存
for (int i = 0; i < rows; i++) {
free(matrix[i]);
}
free(matrix);
}
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
printf("=== 东巴文动态字符串数组 ===\n\n");
int count = 3;
// 分配指针数组
char **strings = (char **)malloc(count * sizeof(char *));
if (strings != NULL) {
// 为每个字符串分配内存
for (int i = 0; i < count; i++) {
strings[i] = (char *)malloc(50 * sizeof(char));
}
// 初始化
strcpy(strings[0], "Hello");
strcpy(strings[1], "东巴文");
strcpy(strings[2], "db-w.cn");
// 输出
printf("字符串数组:\n");
for (int i = 0; i < count; i++) {
printf("strings[%d] = %s\n", i, strings[i]);
}
// 释放内存
for (int i = 0; i < count; i++) {
free(strings[i]);
}
free(strings);
}
return 0;
}
#include <stdio.h>
#include <stdlib.h>
int main() {
printf("=== 东巴文检查返回值 ===\n\n");
// ✅ 正确:检查返回值
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("=== 东巴文使用sizeof运算符 ===\n\n");
// ✅ 正确:使用sizeof
int *ptr1 = (int *)malloc(sizeof(int));
int *ptr2 = (int *)malloc(10 * sizeof(int));
// ❌ 错误:硬编码大小
// int *ptr3 = (int *)malloc(4); // 不同平台可能不同
printf("使用sizeof确保可移植性\n");
free(ptr1);
free(ptr2);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
void noMemoryLeak() {
printf("=== 东巴文避免内存泄漏 ===\n\n");
int *ptr = (int *)malloc(sizeof(int));
if (ptr != NULL) {
*ptr = 100;
printf("ptr = %d\n", *ptr);
// ✅ 正确:释放内存
free(ptr);
ptr = NULL;
}
printf("无内存泄漏\n");
}
int main() {
noMemoryLeak();
return 0;
}
完成本章学习后,请确认:
掌握动态内存分配后,你可以继续学习:
如果遇到问题,欢迎访问 东巴文(db-w.cn) 获取帮助!
东巴文(db-w.cn) - 让编程学习更简单
🎯 东巴文动态内存分配提示:动态内存分配赋予了程序灵活性,但也带来了内存管理的责任。在 db-w.cn,我们会通过大量实例帮你掌握动态内存分配!