动态内存
1、创建动态内存
- 调用创建内存函数malloc()(calloc,realloc),创建内存
char* p = (char* )malloc(1024 * 1024 *1024);//创建1G内存
内存泄漏:
- 动态内存位于堆heap区,需要程序员外部自行管理。
如果创建动态内存后没有释放回收内存会造成内存泄漏。 - 系统自动回收内存:
1 程序退出
2 关机—>内存回收
2、释放回收内存
- 调用释放内存函数free()释放内存。
free(p)
free回收内存的崩溃:
- 1 移动指针,p++,修改头信息;
- 2 越界,尾信息破坏(重新拼接内存);
- 3重复释放
边界标志:
头信息(内存块的字节大小即长度信息,指针前面的相对固定位置)
尾信息
free与NULL
- free释放内存后,原指针会变成野指针,需要将指针置空。
free(p);
p = NULL;
malloc和calloc函数
- calloc分配内存并将内存初始化为0
#include<stdio.h>
#include <malloc.h>
#include <cassert>
int main()
{
int* p = (int*)malloc(10 * sizeof(int));//将分配内存中的一个数组的元素初始化为0
assert(p != NULL);
for (int i = 0; i < 10; i++)
{
p[i] = 0;
printf("%d ", p[i]);
}
printf("\n");
free(p);
int* p = (int*)calloc(10,sizeof(int));//calloc分配内存中的一个数组的元素初始化为0
assert(p != NULL);
for (int i = 0; i < 10; i++)
{
printf("%d ",p[i]);
}
printf("\n");
free(p);
return 0;
}
malloc和realloc函数
- realloc重新分配内存块,用于扩容
#include<stdio.h>
#include <malloc.h>
#include <cassert>
int main()
{
int* m = (int*)malloc(20 * sizeof(int));//重新分配内存块
assert(m != NULL);
for (int i = 0; i < 10; i++)//将p分配内存中的元素依次赋给m分配的内存
{
//*m++ = *p++;
m[i] = p[i];
}
free(p);//释放p分配的内存
p = m;//让p指向m分配的内存,赋值操作
m = NULL;//让m指向空指针
//free(p);//释放新内存
p = (int*)realloc(p, 20 * sizeof(20));//realloc重新分配内存块,用于扩容
free(p);
return 0;
}
realloc,也可以用于缩小内存块大小,此时并没有释放原来的内存块,只是缩小了内存的边界(即,内存块的大小信息)
realloc,扩容后,一般会重新开辟内存块,回收释放掉原来的内存块(在原内存块后面续接内存块的可能性较小),此时不需要回收释放原内存块,否则会报错。