malloc,calloc,realloc的使用方法和注意事项

一,我们先来介绍一下今天的第一个函数malloc:

参数:无符号整形。

返回值:void*的指针,内存开创成功后返回的是内存的起始地址,如果失败,返回NULL;

功能就是开辟指定大小的内存空间,但是不对该内存进行初始化,保留的是不确定的值。

我们在使用该函数的时候要注意对malloc之后的返回值进行强制类型转换,以便达到我们的使用目的。

接下来我们以一个例子来使用一下malloc

#include <string.h>
#include <stdio.h>
#include <errno.h>
int main()
{
	//使用malloc开辟一块内存,并给该内存赋值。
	int* ptr = (int*)malloc(20);//开辟20个字节的空间
	int* p = ptr;
	//判断一下返回值是否正常
	if (p == NULL)
	{
		//显示一下错误信息,并介绍代码的运行
		strerror(errno);
		free(ptr);
		p = NULL;
		ptr = NULL;
		return 1;
	}
	for (int i = 0; i < 5; i++)
	{
		*p = i;
		p++;
	}
	for (int i = 0; i < 5; i++)
	{
		printf("%d ", *(ptr + i));
	}
	//释放
	free(ptr);
	ptr = NULL;
	p = NULL;

	return 0;
}

无论在使用那个动态内存函数开辟的空间,大家在最后使用之后一定要注意用free()释放,释放时使用的时内存的首地址,所以我上面使用了p来进行赋值操作,但是这有点繁琐了,使用一个指针也是能完成上面的要求的,下面说代码的优化:

#include <string.h>
#include <stdio.h>
#include <errno.h>
int main()
{
	//使用malloc开辟一块内存,并给该内存赋值。
	int* ptr = (int*)malloc(20);//开辟20个字节的空间
	//判断一下返回值是否正常
	if (ptr == NULL)
	{
		//显示一下错误信息,并介绍代码的运行
		strerror(errno);

		//这里可以不进行释放,因为我使用了return程序结束之后,内存就释放掉了!
		//free(ptr);
		//ptr = NULL;
		return 1;
	}
	for (int i = 0; i < 5; i++)
	{
		//这样ptr的值就没有改变。
		*(ptr + i) = i;
	}
	for (int i = 0; i < 5; i++)
	{
		printf("%d ", *(ptr + i));
	}
	//释放
	free(ptr);
	ptr = NULL;

	return 0;
}

二,calloc函数:

同样我们还是先来看一下这个函数的返回值和参数以及功能有哪些

参数:num是开辟的字节大小,size是开辟的个数。

返回值:void*类型,开辟内存成功也是返回首地址,失败返回NULL;

与malloc不同的是,calloc会对开辟的内存进行一个初始化的操作,初始化全为0。

 用例:

int main()
{
	//开辟4个字节的内存5个
	int* ptr = (int*)calloc(5, 4);
	//int* ptr = (int*)calloc(5, sizeof(int));

	if (ptr == NULL)
	{
		strerror(errno);
		return 1;
	}
	for (int i = 0; i < 5; i++)
	{
		*(ptr + i) = i;
	}
	for (int i = 0; i < 5; i++)
	{
		printf("%d ", *(ptr + i));
	}

	//释放
	free(ptr);
	ptr = NULL;
	return 0;
}

 calloc相比于malloc更加灵活了一些!,区别就是calloc会对内存初始化为0,而malloc不会。

三,realloc函数:

reaclloc函数可以更改指定内存块的大小

 参数:ptr指向的内存块,size无符号整形

返回值:更改成功返回有两种可能性:

                1,返回值原有的地址,2,返回新的地址

为什么会有这两种情况呢?原因是,当更改的内存和原有的内存是连续的话,更改完之后内存快的地址没有发生改变,返回的就是原地址。如下图:(减小原内存快空间的话返回的肯定是原地址)

并不是所有时刻更改的内存都是连续的,那么当更改的内存并不连续的时候realloc会新开辟一块大的空间,并将原数据拷贝到新开辟的内存快中,并返回新的内存地址!并将原内存块释放掉(自动释放)如下图:

注意,新分配出来的空间也是不进行初始化的!

如果更改不成功的话,返回NULL;

 下面我们对第一例代码进行改造,让得能放下10个数据。

#include <string.h>
#include <stdio.h>
#include <errno.h>
int main()
{
	int* ptr = (int*)malloc(20);
	if (ptr == NULL)
	{
		strerror(errno);
		return 1;
	}

	ptr = (int*)realloc(ptr, 40);
	for (int i = 0; i < 10; i++)
	{
		*(ptr + i) = i;
	}
	for (int i = 0; i < 10; i++)
	{
		printf("%d ", *(ptr + i));
	}
	//释放
	free(ptr);
	ptr = NULL;

	return 0;
}

运行结果:

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

南山忆874

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值