C语言中动态内存函数:malloc、calloc、realloc和free的干货

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、malloc、calloc、realloc和free函数是什么?
  • 二、malloc、calloc、realloc和free的使用步骤
    • 1.引入库
  • 总结


前言

       在我们平时写代码的过程中,程序员可能会有一种需求:那就是我们向内存空间申请大小的时候,如果能自己人为干预的条件下,就可使得空间的利用效率能够大大提高,而不是申请大了造成空间浪费,或者是申请小了不足以使用,下面给大家分享一种动态内存的存储原理,在有需要的时候可以试试动态内存开辟空间。

一、malloc、calloc、realloc以及free函数它们是什么?

(一)malloc函数是什么?

  1. malloc函数是C语言为我们提供的一个动态内存开辟的函数,它的常见的类型为 :                                       void*  malloc  ( size_t  size );
  2. 传入的是空间的大小(单位是字节);传出的是新开辟空间的地址(指针)
  3. 使用malloc函数切记一定要引头文件  #include
  4. molloc函数是在堆区申请开辟空间的,并且向内存申请的是一块连续可用的空间,然后返回一个指向这块空间的指针.
  5. 如果开辟成功,返回一个指向开辟好空间的指针;如果开辟失败,返回一个NULL指针,所以malloc的返回值要做检查.
  6. 由于返回值的类型是void*,因此malloc函数并不知道所开辟空间的类型,具体在使用的时候,程序员根据自己的情况来决定做强制类型转换。

(二)calloc函数是什么?

  1. calloc函数也是C语言为我们提供的一个动态内存开辟函数,它的常见类型为:                                               void*  calloc  ( size_t  num , size_t  size );
  2. 该函数的功能是为num个大小为size的元素开辟一块空间,并且把空间的每个字节初始化为全0.
  3. calloc与malloc函数的区别:                                                                                          malloc函数在返回地址的时候,不对申请的空间做任何初始化,因此每个字节里面放的都是些随机值。                  

    C语言中动态内存函数:malloc、calloc、realloc和free的干货_第1张图片

                                                                                                                                      calloc函数会在返回地址之前把申请的空间的每个字节初始化为全0。C语言中动态内存函数:malloc、calloc、realloc和free的干货_第2张图片
  4. 如果我们对申请的内存空间的内容要求初始化,那么可以很方便的使用calloc函数。
  5. calloc() =  malloc() + memset (0)                 

 (三)realloc函数

  1. realloc函数的出现让动态内存管理更加灵活。
  2. 有时如果我们发现过去申请的空间太小了不够用,有时我们又觉得申请的空间过大了造成了浪费,那为了合理的使用内存,我们一定要会对内存的大小做灵活的调整。那realloc函数就可以做到对动态开辟内存的大小做合理调整。
  3. realloc函数的类型如下: void*  realloc  ( void* ptr  ,  size_t size );
  4. ptr是要调整的内存地址(旧空间的地址),size是调整之后的新大小
  5. 返回值为调整之后的内存起始位置。
  6. 这个函数调整原内存空间大小的基础上,还会将原来内存中的数据移动到新的空间
  7. realloc函数在调整内存空间的时候,存在两种情况:                                                      情况1:原有空间之后有足够大的空间时,要扩展内存就直接原有内存之后直接追加空间,原来空间的数据不发生变化。                                                                                    情况2:原有空间之后没有足够大的空间时,扩展的办法是:在堆空间上另找一个合适大小的连续空间来使用。这样的函数的返回的是一个新的内存地址。                             因此在使用realloc函数时就要多注意一些,要注意以上两种情况。
  8. realloc (NULL,40); 功能上等价于 malloc(40);                                

C语言中动态内存函数:malloc、calloc、realloc和free的干货_第3张图片

 C语言中动态内存函数:malloc、calloc、realloc和free的干货_第4张图片

(四)free函数

  1. 函数free专门是用来做动态内存释放和回收的,函数的类型如下:                                        void*  free ( void* ptr );
  2. free函数只能被用来释放动态开辟的内存。                                                                      如果参数ptr指向的空间不是动态开辟的话,那么free函数的行为是未定义的。              如果参数ptr是NULL指针,则函数什么事情也不做  。
  3. 函数malloc和free都声明在头文件 stdlib.h 中                                                                   

二、使用步骤

1.引入库

针对函数realloc返回的地址是否与源地址相同,我们有如下代码来验证:

#define _CRT_SECURE_NO_WARNINGS 1
#include 
#include 
int main()
{
	int* p = NULL;
	p=(int*)malloc(40);
	if (p == NULL)
	{
		perror("malloc:");
		return;
	}
	//扩容空间
	int* ptr = (int*)realloc(p, 60);
	if (ptr == NULL)
	{
		perror("realloc:");
		return;
	}
	p = ptr;
	//使用空间
	for (int i = 0; i <15; i++)
	{
		*(p + i) = i;
	}
	for (int i = 0; i < 15; i++)
	{
		printf("%d ", *(p + i));
	}
	//释放空间
	free(p);
	p = NULL;
	free(ptr);
	ptr = NULL;
	return 0;
}

C语言中动态内存函数:malloc、calloc、realloc和free的干货_第5张图片

  这是情况1的监视地址。可以发现当扩容很小的空间的时候,realloc是在原空间基础上追加扩容,所以realloc返回的地址就是原来空间的地址。

#define _CRT_SECURE_NO_WARNINGS 1
#include 
#include 
int main()
{
	int* p = NULL;
	p=(int*)malloc(40);
	if (p == NULL)
	{
		perror("malloc:");
		return;
	}
	//扩容空间
	int* ptr = (int*)realloc(p, 80);
	if (ptr == NULL)
	{
		perror("realloc:");
		return;
	}
	p = ptr;
	//使用空间
	for (int i = 0; i <20; i++)
	{
		*(p + i) = i;
	}
	for (int i = 0; i < 20; i++)
	{
		printf("%d ", *(p + i));
	}
	//释放空间
	free(p);
	p = NULL;
	free(ptr);
	ptr = NULL;
	return 0;
}

C语言中动态内存函数:malloc、calloc、realloc和free的干货_第6张图片

 这是情况2的监视地址。可以发现当扩容很大的空间的时候,原空间可能后面的空间大小不足以扩容,这时realloc是在堆空间中另开辟一块空间的地址来返回给realloc函数,所以realloc返回的地址是新的空间的地址。 跟之前的地址是不一样的。


总结

malloc   —— 不初始化空间

 calloc   ——  空间内部初始化全0

realloc   ——  调整内存空间的大小,如果第一个参数是NULL,功能类似于malloc

   free     ——  释放动态开辟的内存空间

提示:以上就是今天要讲的内容,本文仅仅简单介绍了动态内存函数的使用细节以及注意点供各位C语言学习者参观和借鉴,由于本人编程shui如有不足和错误请私信我纠正。

你可能感兴趣的:(c语言)