What is Dynamic Memory Allocation?什么是动态内存分配?
Dynamic memory allocation lets a program request and free memory at runtime, rather than fixing sizes at compile time. This provides flexibility when the required size is not known in advance.
动态内存分配允许程序在运行时申请和释放内存,而不是在编译时就确定内存大小。它在我们事先无法确定所需内存时提供了更大的灵活性。
Memory Layout Overview:内存布局示意图:
+------------------+
| 栈区 | 函数调用、局部变量
+------------------+
| 堆区 | 动态分配的内存 (malloc)
+------------------+
| 静态区 | 全局变量、静态变量
+------------------+
| 代码区 | 程序代码
+------------------+
#include
int *ptr = (int *)malloc(sizeof(int));
if (ptr == NULL) {
printf("内存分配失败\n");
return 1;
}
*ptr = 42;
free(ptr);
Core Memory Allocation Functions核心内存管理函数
1. malloc() - 分配内存
void *malloc(size_t size);
- Args: number of bytes参数:需要分配的字节数
- Return: pointer to memory or NULL on failure返回值:指向分配内存的指针,失败时返回NULL
- Notes: contents are uninitialized特点:分配的内存内容是未初始化的
2. free() - 释放内存
void free(void *ptr);
- Arg: pointer to memory to free参数:要释放的内存指针
- Effect: return memory to the system作用:将内存归还给系统
- Note: only free memory allocated by malloc/calloc/realloc注意:只能释放通过malloc分配的内存
3. calloc() - 分配并清零
void *calloc(size_t num, size_t size);
- Args: number of elements and element size参数:元素数量和每个元素的大小
- Notes: memory is zero-initialized特点:分配的内存会初始化为零
💡 malloc vs calloc
- malloc(size): allocate bytes; uninitializedmalloc(size): 分配size字节,内容未初始化
- calloc(num, size): allocate num×size; zeroedcalloc(num, size): 分配num×size字节,内容初始化为0
- realloc(ptr, size): resize allocationrealloc(ptr, size): 重新分配内存大小
Dynamic Array Creation动态数组创建
The most common use of dynamic allocation is arrays whose size is known only at runtime:动态内存最常见的用途是创建运行时确定大小的数组:
int *create_array(int size) {
int *array = (int *)malloc(size * sizeof(int));
if (array == NULL) {
printf("内存分配失败\n");
return NULL;
}
for (int i = 0; i < size; i++) {
printf("输入第%d个元素: ", i);
scanf("%d", &array[i]);
}
return array;
}
🎯 动态数组操作实例
Let’s write a function to print doubled values of an array:让我们实现一个函数来打印数组的双倍值:
void print_double(int *array, int size) {
for (int i = 0; i < size; i++) {
printf("%d ", array[i] * 2);
}
printf("\n");
}
int main() {
int size;
printf("输入数组大小: ");
scanf("%d", &size);
int *array = create_array(size);
if (array != NULL) {
printf("数组元素双倍值: ");
print_double(array, size);
free(array);
}
return 0;
}
Dynamic Struct Creation动态结构体创建
We can allocate structs dynamically, which is crucial for lists, trees, and other structures:我们可以动态创建结构体,这对于链表、树等数据结构非常重要:
struct movie_review *new_review(char *title, int year, int rating) {
struct movie_review *review =
(struct movie_review *)malloc(sizeof(struct movie_review));
if (review == NULL) {
return NULL;
}
strcpy(review->title, title);
review->release_year = year;
review->rating = rating;
return review;
}
⚠️ 常见内存错误
- Memory leak: allocated but never freed内存泄漏: 分配内存但忘记释放
- Wild pointer: using pointer after free野指针: 释放内存后继续使用指针
- Double free: calling free() twice双重释放: 对同一内存多次调用free
- Out-of-bounds: access beyond allocation越界访问: 访问超出分配范围的内存
Memory Debugging Tools内存调试工具
On Linux, use dedicated tools to detect memory issues:在Linux系统中,我们可以使用专门的工具来检测内存问题:
gcc -g program.c -o program
valgrind --leak-check=full ./program
// ==12345== HEAP SUMMARY:
// ==12345== in use at exit: 0 bytes in 0 blocks
// ==12345== total heap usage: 1 allocs, 1 frees, 1,024 bytes allocated
// ==12345== All heap blocks were freed -- no leaks are possible
💡 调试技巧
- Always check if malloc returned NULL总是检查malloc的返回值是否为NULL
- Set pointer to NULL after free在free后将指针设为NULL避免野指针
- Use valgrind to check leaks使用valgrind定期检查内存泄漏
- Pair every malloc with a free为每个malloc配对一个free
Summary总结
Dynamic allocation is a core skill in advanced C. In this module, you learned:动态内存分配是C语言高级编程的核心技能,本周我们学习了:
- malloc/calloc: ways to allocate dynamicallymalloc/calloc:动态分配内存的方法
- free: importance of freeingfree:正确释放内存的重要性
- Dynamic arrays: sized at runtime动态数组:运行时确定大小的数组
- Dynamic structs: flexible complex data动态结构体:灵活创建复杂数据结构
- Debugging: use valgrind内存调试:使用valgrind检测问题
🚀 下一步学习
After mastering dynamic allocation, we’ll study recursion and the underlying call mechanics.掌握了动态内存分配后,我们将学习递归编程,探索函数调用的底层机制。