文章目录
- 一、前言
- 二、C语言内存分区概述
- 三、动态内存分配函数
- 1. `malloc()` 函数
- 2. `calloc()` 函数
- 3. `realloc()` 函数
- 4. `free()` 函数
- 四、动态内存管理注意事项
- 五、总结
一、前言
动态内存分配允许程序在运行时申请和释放内存,以灵活管理数据。本文将介绍C语言中常用的动态内存分配函数,包括:
malloc()
:分配指定字节的内存,但不会初始化。calloc()
:分配指定数量和大小的内存,并将内存初始化为0。realloc()
:调整已经分配的内存大小。free()
:释放分配的内存。
二、C语言内存分区概述
在C语言中,内存大致分为以下几部分:
- 代码区:存放程序的可执行代码。
- 静态区:存放全局变量和静态变量。
- 栈区:由编译器自动分配和释放,主要用于存放函数参数、局部变量和返回地址。
- 堆区:由程序员手动分配和释放,用于存放动态分配的内存。
动态内存分配主要在堆区进行,程序运行时申请和释放内存,以便灵活使用资源。
三、动态内存分配函数
1. malloc()
函数
malloc()
(memory allocation)用于分配指定字节数的内存块,但不会对内存进行初始化。成功分配后,返回指向该内存块的指针;分配失败时返回 NULL
。
函数原型:
void* malloc(size_t size);
size
:要分配的内存大小(字节)。- 返回值:成功返回指针,失败返回
NULL
。
✅ 示例:
#include <stdio.h>
#include <stdlib.h>int main() {int *arr;int n = 5;// 分配n个整数大小的内存空间arr = (int*)malloc(n * sizeof(int));if (arr == NULL) {printf("内存分配失败\n");return 1;}// 初始化并输出for (int i = 0; i < n; i++) {arr[i] = i + 1;printf("%d ", arr[i]);}// 释放内存free(arr);return 0;
}
✅ 运行结果:
1 2 3 4 5
注意:
malloc
分配的内存中数据是随机的,未初始化。
2. calloc()
函数
calloc()
(contiguous allocation)分配指定数量和大小的内存块,并将内存初始化为0。
函数原型:
void* calloc(size_t num, size_t size);
num
:要分配的元素个数。size
:每个元素的大小(字节)。- 返回值:成功返回指针,失败返回
NULL
。
✅ 示例:
#include <stdio.h>
#include <stdlib.h>int main() {int *arr;int n = 5;// 分配并初始化内存arr = (int*)calloc(n, sizeof(int));if (arr == NULL) {printf("内存分配失败\n");return 1;}// 输出初始值for (int i = 0; i < n; i++) {printf("%d ", arr[i]);}// 释放内存free(arr);return 0;
}
✅ 运行结果:
0 0 0 0 0
calloc
分配的内存自动初始化为0。
3. realloc()
函数
realloc()
(reallocation)用于调整已分配内存的大小,可以扩大或缩小原内存块。
函数原型:
void* realloc(void* ptr, size_t size);
ptr
:原内存块的指针。size
:新的内存大小。- 返回值:成功返回新内存的指针,失败返回
NULL
。
✅ 示例:
#include <stdio.h>
#include <stdlib.h>int main() {int *arr;int n = 5;// 初始分配5个整数大小的内存arr = (int*)malloc(n * sizeof(int));if (arr == NULL) {printf("内存分配失败\n");return 1;}// 初始化for (int i = 0; i < n; i++) {arr[i] = i + 1;}// 扩展内存n = 10;arr = (int*)realloc(arr, n * sizeof(int));if (arr == NULL) {printf("内存扩展失败\n");return 1;}// 新内存赋值for (int i = 5; i < n; i++) {arr[i] = i + 1;}// 输出for (int i = 0; i < n; i++) {printf("%d ", arr[i]);}free(arr);return 0;
}
✅ 运行结果:
1 2 3 4 5 6 7 8 9 10
realloc
在扩展内存时会将原数据保留,但新分配部分的数据可能未初始化。
4. free()
函数
free()
用于释放使用 malloc()
、calloc()
和 realloc()
动态分配的内存。释放后,指针指向的内存不再有效。
函数原型:
void free(void* ptr);
ptr
:指向要释放的内存块。- 无返回值。
✅ 示例:
#include <stdio.h>
#include <stdlib.h>int main() {int *arr = (int*)malloc(5 * sizeof(int));if (arr == NULL) {printf("内存分配失败\n");return 1;}// 使用动态分配的内存for (int i = 0; i < 5; i++) {arr[i] = i + 1;printf("%d ", arr[i]);}// 释放内存free(arr);return 0;
}
✅ 运行结果:
1 2 3 4 5
使用
free()
后,指针仍然指向之前的内存地址,但访问它将产生未定义行为。
四、动态内存管理注意事项
- 内存泄漏问题:未释放动态分配的内存会导致内存泄漏,程序占用的内存不断增加。
- 释放后避免访问:释放内存后访问会产生未定义行为。
- 指针置空:释放内存后,建议将指针置为
NULL
:
free(arr);
arr = NULL;
- 分配失败处理:分配失败时,返回
NULL
,应进行判断:
if (ptr == NULL) {printf("内存分配失败\n");exit(1);
}
五、总结
C语言中的动态内存分配函数包括:
malloc()
:分配指定字节数的内存,不初始化。calloc()
:分配并初始化内存。realloc()
:调整内存大小。free()
:释放内存。
在使用动态内存时,注意内存泄漏、释放后指针置空等问题,以确保程序稳定性。