【C语言】:动态内存管理函数malloc,calloc,realloc和free的介绍的介绍

本文详细介绍了C语言中动态内存分配的三个关键函数malloc、calloc和realloc,以及free函数的使用方法,包括它们的原型、功能、应用场景和注意事项,以帮助开发者有效地管理内存资源。
摘要由CSDN通过智能技术生成

动态内存开辟函数malloc,calloc,realloc和free


我们在向内存申请空间时,一般有如下几种方式:

//第一种:
int  main()
{
int a=10;//申请4个字节,一小块一小块申请
}

//第二种
int main()
{
int arr[10];//申请40个字节,一大块一大块申请
}

这两种方式开辟的空间是固定的,不能变化的。但是对于空间的需求,不仅仅是上述情况,有时候我们需要的空间大小在运行程序的时候才知道。

接下来介绍动态内存函数malloc,calloc,realloc和free,以满足我们对内存的需要。
动态申请的内存在内存的堆区

注意:他们都是库函数,使用时需要引用头文件<stdlib.h> !!!

1.malloc和free函数

首先介绍动态内存开辟函数malloc和free

函数原型为:void *malloc(size_t size)
参数:需要开辟的空间大小,单位字节。

这个函数向内存申请一块连续可用的空间,并返回指向这块空间的指针(这块空间的首地址)。

  1. 如果开辟成功,则返回一个指向开辟好空间的指针
  2. 如果开辟失败,则返回一个NULL指针,因此malloc的返回值一定要做检查。
  3. 返回类型是void*,所以这个函数不知道开辟空间的类型,具体使用时强制类型转换成需要的类型。

free函数是与malloc,calloc,realloc匹配使用的函数,在程序结束时用来释放开辟的空间,防止内存泄漏。
函数原型为:void free( void *p );
意思是释放p所指向的空间。
注意:free必须释放的是动态开辟出来的空间!!

以下是他们的使用方法:

#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#include "errno.h"

int main()
{
int arr[10]={0};

int *p=(int*)malloc(40);//向堆区开辟了40个字节

//int *p(int*)malloc(INT_MAX+1);//开辟失败时

//判断,检查,防止开辟失败
if(p==NULL)
{
printf("%S\n",strerror(errno));//提示错误信息
return 1;//结束运行
}

//使用
int i=0;
for(i=0;i<13;i++)
    {
*(p+i)=i;
   }

//打印
for (i = 0; i < 13; i++)
	{
		printf("%d ", *(p + i));
	}

//释放
free(p);
//此时只是释放了开辟的40个字节,但是变量p内仍然保留原地址,如果这时有人使用了p,这时p是十分危险的,这是一个野指针!!所以要把p置空。
p=NULL;

return 0;
}

开辟成功时运行结果是:

在这里插入图片描述
开辟失败时运行的结果是:
在这里插入图片描述

2.calloc函数

接下来介绍另一个动态内存开辟函数calloc

函数原型为:void *calloc(size_t num,size_t size)
参数是:开辟类型的个数,开辟类型的大小。

这个函数向内存申请一块连续可用的空间,并返回指向这块空间的指针(这块空间的首地址)。

  1. 功能是为num个大小为size的元素开辟一块空间,并且空间里每个字节自动初始化为0。
  2. 与函数malloc的区别只在于calloc会在返回地址之前把申请空间里的每个字节初始化为0。

如果开辟成功,则返回一个指向开辟好空间的指针
如果开辟失败,则返回一个NULL指针,因此calloc的返回值也要做检查。
返回类型是void*,所以这个函数不知道开辟空间的类型,具体使用时强制类型转换成需要的类型。

使用方法如下:

#include "stdio.h"
#include "stdilb.h"
#include "string.h"
#include "errno.h"

//开辟10个整型空间
int *p=(*int)calloc(10,sizeof(int));

//检查判断
if(p==NULL)
{
printf("%s\n",strerror(errno));
return 1;
}

//使用
int i=0;
for(i=0;i<10;i++)
{
*(p+i)=i;
}

//打印
for(i=0;i<10;i++)
{
printf("%d ",*(p+i));
}

//使用完后要释放
free(p);
p=NULL;

return 0;

成功开辟运行后的结果是:

验证其开辟空间后自动初始化为0的代码是:

int main()
{
	int* p = (int*)calloc(10, sizeof(int));

	if (p == NULL)
	{
		printf("%s\n", strerror(errno));
		return 1;
	}

	int i = 0;
	for (i = 0; i < 10; i++)
	{
		printf("%d ", *(p + i));
	}

	free(p);
	p = NULL;

	return 0;
}

运行后的结果是:

3.realloc函数

最后介绍动态内存调整函数realloc

函数原型:void realloc(void ptr,size_t size)
参数:ptr是要调整的内存地址,size是调整之后的新大小

如果调整成功,则返回一个指向调整后空间的指针
如果调整失败,则返回一个NULL指针,因此calloc的返回值也要做检查。
返回类型是void*,所以这个函数不知道开辟空间的类型,具体使用时强制类型转换成需要的类型。

  1. 返回值为调整之后的内存起始位置
  2. 这个函数调整原内存空间大小的基础上,还会将原来内存中的数据移动到新的空间。
  3. realloc在调整内存空间时存在两种情况:
    在这里插入图片描述
    如上图所示,
    情况1为在调整内存空间大小时后面的内存被占用,此时不会再向后调整以致覆盖被占用的内存,而是会重新寻找一块大小合适的内存进行调整,这时ptr指向的是调整后新内存的地址,并且原空间里的数据会自动复制到新空间,原空间也会自动销毁。
    情况2是在调整内存空间大小时后面的内存足够,此时直接调整即可。

使用方法如下:

int main()
{
	int* p = (int*)malloc(40);
	
	if (p == NULL)
	{
		printf("%s\n", strerror(errno));
		return 1;
	}

//使用
	int i = 0;
	for (i = 0; i < 10; i++)
	{
		*(p + i) = i + 1;
	}

	//扩容
	int* ptr = (int*)realloc(p, 80);//不要直接使用p接收,防止调整失败
	if (ptr != NULL)
	{
		p = ptr;
	}

	for (i = 0; i < 10; i++)
	{
		printf("%d ", *(p + i));
	}

	free(p);
	p = NULL;

	return 0;
}

调整成功后的运行结果是:
在这里插入图片描述

  • 49
    点赞
  • 49
    收藏
    觉得还不错? 一键收藏
  • 33
    评论
评论 33
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值