动态内存管理——calloc、realloc
————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;
//}
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!