动态内存管理是指在程序运行期间,根据实际需要动态地分配和释放内存空间的过程。与静态内存分配在编译时就确定内存大小不同,动态内存管理允许程序在运行时根据具体情况灵活地申请和释放内存。
主要通过 malloc 、 calloc 、 realloc 和 free 函数来实现。
malloc
用于分配指定字节数的内存空间;
perror 函数会将当前全局变量 errno 所存储的错误码转换成错误信息并输出到标准错误输出流( stderr )。
使用malloc需要注意的点:
1、检查返回值: malloc 在内存分配成功时,返回指向分配内存起始地址的指针;失败则返回 NULL 。
2、内存释放:使用完 malloc 后,要调用 free 函数释放,防止内存泄。并且释放内存后,应将指针赋值为 NULL ,避免成为悬空指针(指向已释放内存的指针)
3、合理估计内存大小:根据实际需求合理确定要分配的内存字节数,避免分配过大造成内存浪费,或过小导致数据存储不下。
类型转换: malloc 返回的是 void* 类型指针,使用时需根据实际用途进行强制类型转换,使其指4、向所需类型的内存:如 int *ptr = (int *)malloc(10 * sizeof(int)); 。
5、初始化内存: malloc 分配的内存是未初始化的,保留的是不确定的值。如果需要确定的初始值,可使用 memset 等函数进行初始化,如 memset(ptr, 0, 10 * sizeof(int)); 将分配的内存初始化为0。
6、注意系统限制:可分配的内存大小受系统限制,申请内存过大可能导致分配失败。
#include <stdio.h>
#include <stdlib.h>
int main() {
int* arr;
int size = 5;
// 使用malloc分配存储5个整数的内存空间
arr = (int*)malloc(size * sizeof(int));
arr = (int*)malloc(5 * sizeof(char));//申请5个char类型的空间 (还可以这么写
if (arr == NULL) {
//↓perror()作用:将错误码转换成错误信息打印出来
//打印出failed::并且 在failed::后面打印错误信息,
perror("failed::");
return 1;
}
// 为数组元素赋值
for (int i = 0; i < size; i++) {
arr[i] = i + 1;
}
// 输出数组元素
for (int i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");
// 释放动态分配的内存
free(arr);
arr = NULL;
return 0;
calloc
通常用来为数组分配内存,它会把分配的内存初始化为0;
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
// 分配一个包含5个整数的数组的内存空间,并初始化为0
int *intArray = (int *)calloc(5, sizeof(int));
if (intArray == NULL) {
perror("failed::");
return 1;
}
// 输出数组的初始值,验证是否已初始化为0
int i = 0;
for (i=0; i < 5; i++) {
printf("intArray[%d] = %d\n", i, intArray[i]);
}
free(str);
return 0;
}
运行结果(calloc分配的内存初始化为0)
realloc
可改变已分配内存块的大小;
或者↓
int main() {
// 分配一个包含5个整数的数组的内存空间,并初始化为0
int* ptr = (int*)malloc(5*(sizeof(int)));
if (ptr == NULL) {
perror("failed::");
return 1;
}
// 输出数组的初始值,验证是否已初始化为0
int i = 0;
for (i = 0; i < 5; i++) {
ptr[i] = 7; //将ptr[]中每个元素置成7
printf("intArray[%d] = %d\n", i, ptr[i]);
}
//空间不够用? 那就扩大空间(也叫扩容)
int* addptr = (int*)realloc(ptr,10 * (sizeof(int)));
for (i = 0; i < 5; i++) {
ptr[i] = 9; //将ptr[]中每个元素置成7
printf("intArray[%d] = %d\n", i, ptr[i]);
}
//释放指针
free(addptr);//(只释放后面的指针就好了)
addptr = NULL;
return 0;
}
free
用于释放不再使用的内存空间。
free 函数用于释放先前通过 malloc 、 calloc 或 realloc 函数分配的动态内存空间。
注意事项
释放非动态分配的内存会导致未定义行为。
只能释放一次动态分配的内存块,重复释放同一指针会导致程序出现错误。
释放内存后,应将指针设置为 NULL ,防止悬空指针。
注意!!!释放的是动态内存空间!!!
当你使用这些函数分配内存后,在不再需要使用该内存时,应该使用 free 函数来释放它,以便让系统回收资源,避免内存泄漏。
好了 下课!!!!!!!