3.calloc函数(所属stdlib.h头文件)
? ? ? ? 此函数与malloc函数非常相似,都是属于动态内存开辟函数。且他们的返回值都是void*(函数原型:void* calloc(num,size_t size)),这里的size_t类型是unsigned int 类型。
说明:1.函数的功能是为num个大小的元素开辟一块空间,并且把空间的每个字节都初始化为0.
????????? ?2.与函数malloc的区别只在于calloc会在返回地址之前把申请的空间的每个字节初始化为0.
????????? ?3.也会和malloc函数一样存在开辟空间失败的情况。
如下代码:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
int main()
{
int* p=(int*)calloc(10,sizeof(int));
if(p==NULL)
{
printf("%s",strerror(errno));
}
else
{
int i=0;
for(i=0;i<10;i++)
{
printf("%d ",*(p+i));
}
}
free(p);
p=NULL;
return 0;
}
这段代码与malloc函数开辟的动态内存空间的差异不大,malloc函数开辟动态内存时不会初始化,是直接把开辟好的空间返回来。而calloc函数开辟动态内存时候会把内存里面的每个字节全部初始化为0再返回空间,工作量要大一些,效率就要低一些。总结来说,这两个函数各有各的好,你什么情况下需要那个函数自行选择。
2.realloc函数(所属stdlib.h头文件)
? ? ? ? 这个函数比较重要,大家要仔细看看。????????????有时候我们发现过去申请的空间太大或太小了,我们要怎么调大这个空间或调小这个空间呢?这就要用到我们的realloc函数。
该函数原型:void* realloc(void* ptr,size_t size)
? ? ? ? ?特点:
- ptr是要调整的内存地址。
- size是调整为多大的内存空间大小。
- 返回值为调整之后的内存起始位置。
- 这个函数调整原内存大小的基础上,还会将原来内存中的数据移动到新的空间。
- 此函数也存在调整空间失败的情况,若调整失败返回空指针。
- realloc在调整内存空间的是存在两种情况
- 原内存空间后,没有能足够容纳调整后的空间。
- 原内存空间后,又能够足够容纳调整后的空间。 ? ? ?
???????如下内存布局图:
第一种realloc调整空间情况
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
第二种realloc函数调整内存空间情况
realloc函数使用的注意事项:
? ? ? ? 假设现在我们要调大一块空间,但是后面我们调整失败了,刚刚上面提到,调整失败会返回一个空指针,那么试想一下若我们直接把调整过后的空指针直接赋值给指向原内存空间的指针,本来我们高高兴兴得添加内存空间,然后由于某些原因导致添加空间失败返回一个空指针接着直接赋值给指向原内存空间的指针,这不是导致既没有添加成功内存空间,又让指针成为空指针导致你下次再想用原来空间的数据时找不到了那块空间了形成非法访问,岂不是人财两空?所以我们在使用realloc函数调整内存空间时不要直接把reallc返回值交给指向原内存空间的指针,应该先创建一个中间指针来接收realloc函数的返回值判断他是否为空指针,若不为空指针再赋值给指向原内存空间的指针就能很好的解决这个隐患。
如下代码实例:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<errno.h>
int main()
{
int* p=(int*)malloc(5*sizeof(int));
int i=0;
int* ptr=realloc(p,5*sizeof(int));
if(ptr==NULL)
{
printf("%s",strerror(errno));
}
else
{
p=ptr;
for(i=0;i<10;i++)
{
printf("%d ",*(p+i));
}
}
free(p);
p=NULL;
return 0;
}
? ? ? ? ? ? 2.如果p指向的空间之后没有足够的内存空间可以追加,则realloc函数会重新找一个新的内存区域,并且开辟一块满足需求的空间,并且把原来内存中的数据拷贝过来,释放旧的内存空间。