1 前言
堆区(Heap)是程序运行时用于动态分配内存的一块内存区域。在C语言中,可以使用动态内存分配函数(如 malloc()
、calloc()
、realloc()
)在堆区分配内存,并使用相应的释放函数(如 free()
)释放已分配的内存。
在C语言中,可以使用动态内存分配函数在堆区中分配内存。常用的动态内存分配函数有以下三个:
2 分配数据类型
动态分配内存函数可以分配任意类型的数据,包括但不限于以下类型:
- 基本数据类型(例如
int
、float
、char
、double
等) - 结构体(自定义的结构体类型)
- 数组(一维数组、二维数组等)
- 指针(包括指向基本类型和自定义类型的指针)
- 动态创建的字符串(使用字符数组或字符指针)
3 malloc()
函数
- 函数原型:
void* malloc(size_t size)
- 用途:用于分配指定大小的内存块
- 参数:需要分配的内存大小(以字节为单位)
- 返回值:指向分配内存的指针(
void*
类型) - 特点:
- 只分配内存空间,并不初始化其内容
- 分配的内存块的内容是未定义的,可能包含旧数据
int *ptr = (int *)malloc(sizeof(int)); // 分配一个 int 大小的内存块
if (ptr == NULL) {
printf("内存分配失败\n");
return 1;
}
int *ptr = (int *)malloc(sizeof(int)*n); // 分配n个 int 大小的内存块
if (ptr == NULL) {
printf("内存分配失败\n");
return 1;
}
char *ptr = (char *)malloc(sizeof(char)); // 分配一个 char 大小的内存块
if (ptr == NULL) {
printf("内存分配失败\n");
return 1;
}
char *ptr = (char *)malloc(sizeof(char)*n); // 分配n个 char 大小的内存块
if (ptr == NULL) {
printf("内存分配失败\n");
return 1;
}
4 calloc()
函数
- 函数原型:
void* calloc(size_t num, size_t size)
- 用途:用于分配指定数量和大小的内存块,并将其初始化为零
- 参数:需要分配的元素数量和每个元素的大小(以字节为单位)
- 返回值:指向分配内存的指针(
void*
类型) - 特点:
- 分配的内存块大小为
num * size
字节 - 分配的内存块被初始化为零
- 适用于需要初始化内存的情况,如数组或结构体
- 分配的内存块大小为
#include <stdio.h>
#include <stdlib.h>
int main() {
int numElements = 5;
int elementSize = sizeof(int);
int* arr = (int*)calloc(numElements, elementSize);
if (arr == NULL) {
printf("内存分配失败\n");
return 1;
}
// 释放内存
free(arr);
arr = NULL;
}
5 realloc()
函数
- 函数原型:
void* realloc(void* ptr, size_t size);
- 用途:用于重新分配已分配内存块的大小或分配新的内存块
- 参数:指向原始内存块的指针和所需的新大小(以字节为单位)
- 返回值:指向重新分配后的内存的指针(
void*
类型) - 特点:
- 可以增加或减小已分配内存块的大小
- 如果分配成功,会返回重新分配后的内存块指针
- 如果分配失败,返回值为
NULL
,原内存块仍然有效
realloc()
函数接受两个参数,ptr
表示原始内存块的指针,size
表示需要重新分配的内存大小(以字节为单位)。它可以用于以下三种情况:
- 增加已分配内存的大小:如果
ptr
非空且size
大于原分配大小,则会重新分配更大的内存块,并将原有数据拷贝到新分配的内存中。返回的是指向重新分配内存起始位置的指针。 - 减小已分配内存的大小:如果
ptr
非空且size
小于原分配大小,则会重新分配更小的内存块,并将部分数据拷贝到新分配的内存中。返回的是指向重新分配内存起始位置的指针。 - 分配新的内存块:如果
ptr
为空指针,则realloc()
的行为等同于malloc()
,会分配指定大小的新内存块,并返回指向该内存块的指针。
#include <stdio.h>
#include <stdlib.h>
int main() {
int numElements = 5;
int* arr = (int*)malloc(numElements * sizeof(int));
if (arr == NULL) {
printf("内存分配失败\n");
return 1;
}
// 增加已分配内存的大小
int newNumElements = 10;
int* newArr = (int*)realloc(arr, newNumElements * sizeof(int));
if (newArr == NULL) {
printf("内存重新分配失败\n");
free(arr);
return 1;
}
// 使用重新分配的内存块
for (int i = 0; i < newNumElements; i++) {
newArr[i] = i + 1;
printf("%d ", newArr[i]);
}
// 释放内存
free(newArr);
newArr = NULL;
return 0;
}