————calloc
void* calloc(size_t num, size_t size);
函数的功能是为 num 个大小为 size 的元素开辟一块空间,并且把空间的每个字节初始化为0。
与函数 malloc 的区别只在于 calloc 会在返回地址之前把申请的空间的每个字节初始化为全0。
//#include <stdio.h>
//#include <stdlib.h>
//#include<errno.h>
//int main()
//{
// int* p = (int*)calloc(10,4);
// if (NULL == p)
// {
// printf("%s ",strerror(errno));
// return 1;
// }
// //打印
// int i = 0;
// for (i = 0; i < 10; i++)
// {
// printf("%d ",*(p+i));
// }
// free(p);
// p = NULL;
// return 0;
//}//结果为:0 0 0 0 0 0 0 0 0 0
在什么时候选择calloc而不是malloc?(其关系类似于calloc=malloc+memset(内存设置))
//答:在我们想初始化时,就采取calloc
//————realloc头文件<stdlib.h>或<malloc.h>
realloc函数的出现让动态内存管理更加灵活。
有时会我们发现过去申请的空间太小了,有时候我们又会觉得申请的空间过大了,那为了合理的时
候内存,我们一定会对内存的大小做灵活的调整。那 realloc 函数就可以做到对动态开辟内存大小
的调整。
函数原型如下:
void* realloc(void* ptr, size_t size);
void* ptr:指向要调整的那块空间的起始地址
size_t size:希望把其调整为多大的一块空间的大小
返回值为调整之后的内存起始位置。
这个函数调整原内存空间大小的基础上,还会将原来内存中的数据移动到新的空间。
realloc在调整内存空间的是存在两种情况:
情况1:原有空间之后有足够大的空间
情况2:原有空间之后没有足够大的空间(追加空间时可能会占用其他空间)
1.当是情况1 的时候,要扩展内存就直接原有内存之后直接追加空间,原来空间的数据不发生变化。
2.当是情况2 的时候,原有空间之后没有足够多的空间时,扩展的方法是:在堆空间上另找一个合适大小的连续空间来使用,
原有的空间中,realloc把原有的数据拷贝到新的空间中之后,会把原有的空间释放掉。
(另找的空间大小为原有的大小+追加空间的大小)这样函数返回的是一个新的内存地址。
3. 常见的动态内存错误
//#include <stdlib.h>
//#include <errno.h>
//#include <stdio.h>
//int main()
//{
// int*p = (int*)malloc(40);//malloc要申请空间,malloc函数是调用操作系统提供的接口,然后去堆区上申请空间的。
// //每次申请空间,都会打断操作系统的执行,然后让操作系统帮我们去申请,申请后操作系统再继续执行
// if (NULL == p)
// {
// printf("%s\n",strerror(errno));
// return 1;
// }
// //在40个字节中放入 1 2 3 4 5 6 7 8 9 10
// int i = 0;
// for (i = 0; i < 10; i++)
// {
// *(p + i) = i + 1;
// }
// //扩展容量
// //int p = realloc(p, 80);//返回追加后空间的地址,不可以再用原有的地址,因为当扩容时,
// //若扩容过大,导致失败(崩溃),即p就被赋值为了NULL,也将原有的丢失了,所以不可以用原有的变量接收原有的变量
// int* ptr = (int*)realloc(p,80);
// if (ptr !=NULL)//判断现在反回的是否为NULL
// {
// p = ptr;
// }
// //使用
// //现在的100个字节中,前5个字节还是1 2 3 4 5
// for (i = 0; i < 10; i++)
// {
// printf("%d ",*(p + i));
// }
// free(p);
// p = NULL;
// return 0;
//}//结果为:1 2 3 4 5 6 7 8 9 10
注意:如果我们在内存中频繁使用malloc,效率会下降(每一次开辟空间,申请,释放都需要空间),
若内存碎片很多,且没有很好的利用的话,会导致内存被碎片化
在软件工程中有“内存池”的概念(可以解决频繁malloc的问题)
我们想内存申请一块满足我们当前需要的一块内存,然后程序内部自己用内存池的方式来维护这块空间
realloc也可以实现malloc的功能
//#include<stdlib.h>
//int main()
//{
// realloc(NULL, 40);//等同于mallc(40)
// return 0;
//}