在C语言中,动态内存分配是指在程序运行时根据需要动态申请内存空间,以便在程序的不同阶段存储和使用数据。动态内存的分配与释放需要一组函数来实现,包括malloc、calloc、realloc和free。
malloc: 函数用于分配指定大小的内存块,并返回指向该内存块起始地址的指针。语法为:void *malloc(size_t size);
calloc: 函数用于分配指定数量和大小的内存块,并将内存块中的每个字节初始化为0。语法为:void *calloc(size_t num, size_t size);
realloc: 函数用于重新分配已经分配的内存块的大小,可以增大或减小内存块的大小。语法为:void *realloc(void *ptr, size_t size);
free: 函数用于释放通过malloc、calloc或realloc函数分配的内存块,以便将其归还给系统。语法为:void free(void *ptr);
动态内存分配区域:堆(heap),很大接近可用内存,内存申请和销毁需要程序自行管理?内存什么情况还给系统: 1.程序(进程)退出 2.关机(重启)?局部变量:定义在函数内部的变量,包括形参,在栈(stack)中,作用域在函数内部有效,生存周期:进入函数 创建,退出函数销毁?void :没有,可以修饰返回值或参数列表 void *:通用指针,仅仅只标记地址,不包含类型信息?应用场景:?1.需要根据变量作为长度定义数组?2.函数结束后还需要继续使用的内存(例如返回局部数组的地址,链表)3.长度较大的数组(大内存,超过栈1M的大小)
1.需要根据变量作为长度定义数组
2.函数结束后还需要继续使用的内存(例如返回局部数组的地址,链表)
正确的写法
3.长度较大的数组(大内存,超过栈1M的大小)
calloc会把动态申请的内存每个单元初始化为0.
1.越界2.移动指针?3.重复释放或者释放非动态内存
#include<stdio.h>
#include<stdlib.h>
//1.越界
int main()
{
int n = 10;
int* arr = (int*)malloc(n);
assert(arr != NULL);
for (int i = 0; i < n; i++)
arr[i] = i;
for (int i = 0; i < n; i++)
printf("%d ", arr[i]);
printf("\n");
free(arr);
return 0;
}
//2.移动指针
int main()
{
int n = 10;
int* arr = (int*)malloc(n * sizeof(int));
assert(arr != NULL);
for (int i = 0; i < n; i++)
{//arr[i] = i;
*arr = i;
arr++;
}
printf("\n");
free(arr);
return 0;
}
//重复释放同一段内存
int main()
{
int n = 10;
int* arr = (int*)malloc(n * sizeof(int));
assert(arr != NULL);
for (int i = 0; i < n; i++)
{
arr[i] = i;
}
printf("%p\n", arr);
free(arr);
printf("%p\n", arr);//arr是野指针
free(NULL);//可以
//free(arr);//崩溃,重复释放
return 0;
}