C语言:辨析malloc,realloc,calloc三个动态内存函数

    这三个函数都是动态开辟一个空间,同时这个空间大小也是可以动态变化的。这三个函数是内存中的堆区的函数,所开辟的空间是堆区的空间。

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的使用必须是动态分配内存才可以,其他的不可以。

  • 13
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值