由开发人员负责分配和回收的内存区:堆区
1、特点:
由开发人员分配和回收。如果没有回收会造成程序泄露,导致程序崩溃。
2、堆区分配内存的函数
作用:
指定分配存储空间的大小(字节数),将分配的存储空间的起始地址返回。
堆内存是使用地址操作的,地址存储在对应的指针变量中。
Malloc函数
语法:
void * malloc(size)
说明:
void * 表示无类型指针
size 表示分配多大的存储空间,单位是字节数。
Malloc分配的内存空间不会把原内存的数据清空。
如:在堆区存储n个整型数
int * p =malloc(sizeof(int) * n);
每个整形数的字节数是:sizeof(int),分配几个就乘以几。
在堆区存储4个整型数(4个整型数的存储空间是连续的),分别把21、22、23、24存储在堆区。指针名可以当做数组名使用,都指向数组的首元素地址。
int * r =malloc(sizeof(int) * 4);
*r = 21;
*(r+1) = 22;
*(r+2) = 23;
*(r+3) = 24;
for (int i = 0; i< 4; i++) {
printf("%d\n", *(r+i));
// printf("%d\n", r[i]);语法糖 数组名[ ]
}
在堆区存储一个人名(拼音),分配的是n个连续的存储char类型
char * p =malloc(sizeof(char) * 20);
strcpy(p,"zhangsan");//字符串不能直接赋值,需要使用strcpy函数。
printf("%s\n",p); // %s读取的是字符串的起始地址,字符数组的首地址即p指向的。
随机产生10个30~45之间的随机数,存储在堆内存中,在此例中,同样的,指针p的功能可以和数组名一样使用,也可以使用*(p+i).
int * p =malloc(sizeof(int) * 10);
for (int i = 0; i< 10; i++) {
p[i] = arc4random() % 16 + 30;
printf("%d ", p[i]);
}
Calloc函数:
void * calloc(int n,size_t size);
语法:
在堆内存中分配n*size个字节的存储空间,并返回地址。
说明:
基本用法和malloc一致,
不同之处:
calloc中字节数的大小和数量分开写。
calloc会将分配的存储空间中的原始数据清空,效率比malloc低。
如:
在堆区存储5个15~35整型数
p = calloc(5,sizeof(int));
for (int i = 0; i< 5; i++) {
p[i] = arc4random() % 21 + 15;
printf("%d ", p[i]);
}
Recalloc函数:realloc(void*, size_t);
void *realloc(void*p, size_t newSize);
在给定的地址空间(p)基础上,如果当前指针上空间足够,那么将地址扩大,如果空间不足,那么重新找一块新的地址按照newSize大小分配空间,将原有数据从头到尾拷贝到新分配的内存区域,然后释放原来的指针指向的内存区域(自动释放,不需要free).
如:
分配存储空间
int * p_old =malloc(10);
重新分配存储空间
int * p_new =realloc(p_old, 20);
printf("%p%p\n", p_old, p_new);
新地址和旧地址随着设定的分配空间的大小而由不同的值。
3、内存释放、内存泄露和野指针
堆内存回收,内存释放
语法:voidfree(void *);
例:
在堆内存中存储一个整型数
需要在堆内存存储数据时,分配内存
int *p =malloc(sizeof(int));
使用已经分配好的堆内存
*p = 120;
printf("%d\n",*p);
当不需要使用某个内存时,回收内存。
free(p);
注意:这里的内存数据是标记删除。即告诉内存这块区域删除了,而实际上内存的数据扔在内存中,但是无法访问。
内存泄露:
如果分配的内存在使用后忘记释放,在之后分配的指针又指向没有释放的内存,则称为内存泄露,将会引起程序崩溃。
int *p = NULL;// 此时,指针p是空指针
p =malloc(sizeof(int));// 此时,指针p指向堆内存的某个位置
p =malloc(sizeof(int));// 此时,指针p指向另一个位置
*p = 100;
printf("%d\n",*p);
free(p);// 回收内存
此例在第一个分配的存储空间,出现内存泄露。如果在第二次分配之前加上free(p);这句话,就不会出现内存泄露。
野指针:通过指针访问了已经被回收的内存
int *p =malloc(sizeof(int));
*p = 100;
printf("%d\n",*p);
free(p);
printf("%d\n",*p)//此时,p是野指针