这三个函数都是动态开辟一个空间,同时这个空间大小也是可以动态变化的。这三个函数是内存中的堆区的函数,所开辟的空间是堆区的空间。
malloc:
#include<stdlib.h>
void* malloc (size_t size);
malloc这个函数向内存申请一块连续可用的空间,并返回指向这块空间的指针。
首先我们应该开辟空间之前,应该想想我们将开辟什么类型的。
比如:假如我们要开辟整型变量的空间
int *p=(int *)malloc(40);
括号中的int *,因为malloc返回的是void *类型,所以我们需要强制类型转换为我们需要的指针类型。
40 表示的是开辟这块空间的大小,单位是字节。
开辟完成后我还需要进行判断,看看是否开辟成功了,因为如果内存不够,开辟空间就会失败。所以我们需要进行判断是否成功。
int main()
{
int* p = (int*)malloc(40);
if (p == NULL)
{
perror("malloc fail");//将错误消息,并将其打印到控制台上
exit(-1);//退出
}
//开辟成功
for (int i = 0; i < 10; i++)
{
printf("%d\n", *(p + i));
}
free(p);//释放动态申请内存
p=NULL;//防止释放后成为野指针
return 0;
}
为什么打印出来都是-842150451呢?
因为malloc函数申请空间成功后,就直接返回这块空间的起始地址,不会初始化这块空间的内容。
最后我们还需要进行最后一个操作
因为malloc申请的内存空间 ,当程序退出时,会返回给操作系统,如果程序不退出时,申请的内存空间不会主动释放,就会造成内存泄漏。
这个时候就要使用free函数,进行释放那块空间,然而释放后,p指向的空间就会销毁,p也就会成为野指针,我们就要将p置于空指针。
calloc:
#include<stdlib.h>
void* calloc (size_t num, size_t size);
函数的功能是为 num 个大小为 size 的元素开辟一块空间,并且把空间的每个字节初始化为0。
与函数 malloc 的区别只在于 calloc 会在返回地址之前把申请的空间的每个字节初始化为全0。
int main()
{
int* p = (int*)calloc(10,sizeof(int));
if (p == NULL)
{
perror("malloc fail");
exit(-1);
}
//开辟成功
for (int i = 0; i < 10; i++)
{
printf("%d\n", *(p + i));
}
//释放
free(p);
p=NULL;
return 0;
}
如果我们对申请的内存空间的内容要求初始化,那么可以很方便的使用calloc函数来完成任务
realloc:
#include<stdlib.h>
void* realloc (void* ptr, size_t size);
ptr表示的是修改大小的内存地址,size表示的是调整之后新大小
realloc函数的出现让动态内存管理更加灵活。
有时会我们发现过去申请的空间太小了,有时候我们又会觉得申请的空间过大了,那为了合理的时候内存,我们一定会对内存的大小做灵活的调整。那 realloc 函数就可以做到对动态开辟内存大小
的调整
realloc调整大小时,会有两种可能
情况1:原有空间之后有足够大的空间,可以调整。
这样子就直接在后面追加。
情况2:原有空间之后没有足够大的空间,不可以调整,则realloc会寻找一个合适的连续空间使用,将原来的内存数据复制进来,返回新的内存空间地址,将原来的空间释放掉。
代码演示如下
int main()
{
int* p = (int*)calloc(10,sizeof(int));
if (p == NULL)
{
perror("calloc fail");
exit(-1);
}
for (int i = 0; i < 10; i++)
{
p[i] = i;//等价于 *(p+i)=i
}
int* ptr = (int*)realloc(p, 80);
//开辟成功就把新地址传给p
//如果不用ptr的话,假如后面寻找不到合适的空间,也会把原来的p给释放。
if (ptr != NULL)
{
p = ptr;
}
else
{
perror("realloc fail");
exit(-1);
}
for (int i = 0; i < 20; i++)
{
printf("%d\n", p[i]);
//因为后面十个元素没有赋值,就会打印成随机数
}
free(p);
p = NULL;
return 0;
}
注意:
用完这三个函数,必须要free,不然会造成内存泄漏。
free的使用必须是动态分配内存才可以,其他的不可以。