• 15. 《C语言》——【如何动态内存开辟】


    在这里插入图片描述

    亲爱的读者,大家好!我是一名正在学习编程的高校生。在这个博客里,我将和大家一起探讨编程技巧、分享实用工具,并交流学习心得。希望通过我的博客,你能学到有用的知识,提高自己的技能,成为一名优秀的程序员。如果你有任何疑问或建议,请随时在评论区留言,让我们一起成长进步!现在,让我们开始这场知识之旅吧!



    🚀个人主页:FEN03
    📚收入专栏:C语言

    在这里插入图片描述




    📚前言

    为什么需要动态内存开辟,如何向内存申请空间?接下来,就让我们去探讨吧~


    📘1. 为什么要动态内存分配❓


    在先前,我们开辟内存的方法无非是在栈区创建一个变量,或者说一个数组。

    #include
    int main()
    {
    	int a = 0; //在栈区开辟了4个字节的空间
    	int arr[10] = { 0 }; //在栈区开辟了40个连续字节的空间
    	return 0; 
    }
    

    这2种内存开辟,都存在着2种特点

    1. 内存开辟的大小是固定的了。
    2. 数组在创建时,必须是指定它的长度,一旦确定大小后不能再进行更改

    为了迎合更高的要求,上述的情况就不能满足了。那么为了解决这一问题,C语言引入了动态内存开辟,这样程序员就可以灵活的去申请和释放空间。

    那么接下来就让我们探索如何去动态的向内存开辟。


    📗2. 如何去动态内存开辟❓

    那么为了实现动态内存的开辟,C语言提供了4个函数,那么接下来,就让我们去学习如何使用这些函数吧~⬇️


    🔖2.1 malloc

    为了实现动态内存开辟,C语言提供了malloc函数。

    函数语法形式:

    void* malloc (size_t size);
    

    这个函数能够向内存开辟一块连续可用的空间,并且会返回指向这块内存空间的指针。

    1. 如果内存开辟成功,则会返回指向这块开辟好的内存的指针。
    2. 如果内存开辟失败,则会返回NULL,所以当我们使用malloc函数时,一定要检查是否开辟成功。
    3. malloc函数的返回类型是void* ,这是因为malloc函数并不知道程序员要开辟内存空间的类型,所以当程序员使用时由自己决定返回类型。
    4. 如果size为0,这一行为是标准未定义的,而且也没必要,最终的结果也是编译器决定的。

    使用malloc函数需要包含头文件:

    #include
    

    我们可以使用malloc来开辟下内存空间:

    
    #include
    #include
    int main()
    {
    	//向内存开辟40个字节
    	int*p = (int*)malloc(10 * sizeof(int));  
    	//使用if语句来判断是否开辟成功,如果失败则提示错误信息以及提前结束
    	if (p == NULL)
    	{
    		perror("malloc"); 
    		return 1; 
    	}
    
    	//...... 
    
    	return 0; 
    }
    

    我们进行调试看看是否开辟成功?

    在这里插入图片描述

    我们看到已经内存开辟成功了,这些值都是cd,也就是一些随机值。

    但是malloc只是这样使用吗,其实并不是,malloc是需要搭配free函数使用的。接下来,就让我们介绍free函数吧~ ⬇️


    🔖2.2 free

    C语言提供了free函数,那么free函数有什么用❓,我们在前边介绍了malloc函数,是用来向内存申请空间的,那么free函数就是专门用来对动态内存开辟的空间进行释放和回收。
    在生活中,我们都知道有借有还,再借不难。那么在内存中也是这个道理。


    free函数的原型如下:

    void free (void* ptr);
    
    1. 如果参数ptr指向的内存空间不是动态内存开辟的,那么free函数的行为是未定义的。
    2. 如果参数ptr是NULL,则函数什么事都不做。

    free和malloc所包含的头文件一样。

    #include
    

    如何与malloc搭配使用❓❓❓

    代码如下:

    #include
    #include
    int main()
    {
    	//向内存开辟40个字节
    	int*p = (int*)malloc(10 * sizeof(int));  
    	if (p == NULL)
    	{
    		perror("malloc"); 
    		return 1; 
    	}
    
    	//使用...... 
    
    	//释放内存空间
    	free(p); 
    	p = NULL; 
    
    	return 0; 
    }
    

    这样free函数就能够释放p所指向的动态内存开辟的内存空间,那么为什么还需要把p置为NULL呢?

    是因为,free函数虽然已经释放掉了开辟的内存空间,但是指针p还是指向这一空间,为了避免野指针,所以置为了NULL。


    🔖2.3 calloc

    动态内存开辟的函数不仅仅是malloc函数,C语言还提供了另一种函数:calloc

    calloc函数原型:

    void* calloc (size_t num, size_t size);
    
    1. 函数有2个参数,第一个 num 为个数,第二个 size 为字节大小,那么它会开辟程序员所要求的内存空间,并且把空间的每一个字节初始化为0(malloc,值都是cd(随机值))。
    2. 当内存开辟成功,返回的是指向该内存的指针;失败时,返回NULL ,所以当我们使用时,也和malloc一样,需要检查。

    calloc函数如何向内存申请空间呢?让我们接着往下看⬇️⬇️⬇️

    当我需要向内存申请40个字节大小时:

    #include
    #include
    int main()
    {
    	//calloc向内存申请40个字节空间  
    	int* p  = (int*)calloc(10, sizeof(int)); 
    	//判断是否开辟成功
    	if (p == NULL)
    	{
    		perror("calloc"); 
    		return 1; 
    	}
    	//使用..... 
    	
    
    	//释放内存空间
    	free(p); 
    	p = NULL;    
    	return 0;
    }
    

    结果如何? 让我们来调试看看吧~

    在这里插入图片描述

    我们观察到,calloc函数向内存开辟的40个字节成功,并且每一个字节初始化为0。

    calloc函数和malloc函数都是向内存申请空间,既然是申请,那么也需要归还内存空间,一样的都是需要free函数释放把内存还给系统。


    🔖2.4 realloc

    在前边,我们介绍了malloc函数和calloc函数以及free函数,最后我们介绍realloc函数。

    那么我们需要先了解,realloc函数有什么用存在的意义是什么?

    其实是为了让动态内存开辟更加的灵活,有时候,我们使用malloc或者calloc申请内存空间时,可能到某一时间段发现空间太大了或者不够用小了。
    那么为了对内存空间进行调整,C语言呢就提供了realloc函数,这样我们就可以对内存的大小进行灵活的调整。


    realloc函数原型:

    void* realloc (void* ptr, size_t size);
    
    1. ptr是需要调整的内存地址
    2. size是调整后的大小
    3. 返回值为调整后的内存起始位置
    4. 这个函数调整会在原内存空间的基础上,还会将原来内存中的数据移动到新的内存空间
    5. realloc函数在调整内存空间时,会分为2中情况:
      情况1:当原有空间之后有着足够大的空间,那么就会在原有空间的基础上,调整大小。
      情况2:当原有空间之后没有足够大的空间,那么会另开辟一块新的空间,并且把原有空间移到新空间,再进行调整,原有空间会被释放
      在这里插入图片描述

    那么如何使用realloc函数开辟内存空间? 接着往下看吧~⬇️⬇️⬇️

    #include
    #include
    int main()
    {
    	//malloc向内存开辟40个字节
    	int* p = (int*)malloc(10 * sizeof(int));
    	if (p == NULL)
    	{
    		perror("malloc");
    		return 1;
    	}
    
    	//发现不够用,那么使用realloc函数调整内存大小
    	//调整为80个字节
    	int* ptr = (int*)realloc(p, 20 * sizeof(int));  
    	if (ptr != NULL)
    	{
    		p = ptr; 
    		ptr = NULL;  
    	}
    	else
    	{
    		perror("realloc"); 
    		return 1; 
    	}
    
    	//使用..... 
    
    
    
    	//释放内存空间
    	free(p);
    	p = NULL;
    
    	return 0;
    }
    
    

    是否开辟成功?我们进行调试看看

    在这里插入图片描述

    我们可以看到之前malloc函数开辟的内存为40个字节,经过realloc函数调整大小后,为80个字节。


    👋结束语

    非常感谢您花时间阅读我的博客,希望我的分享能为您带来收获。如果您对本文有任何想法或疑问,欢迎在评论区留言交流。如果您喜欢我的博客,请继续关注,我会定期更新更多精彩内容。最后,别忘了行动起来的力量,让我们一起实践这些方法,见证自己的成长和进步!

    那么到此,关于动态内存开辟就讲解完了~

    再见,祝您生活愉快!

    在这里插入图片描述


  • 相关阅读:
    CountDownTimer实现倒计时获取验证码/添加动画
    实现真正的高性能高并发的上亿级别秒杀系统!
    Linux系统安装MongoDB流程
    Django笔记三十之log日志记录详解
    背包问题汇总(01背包、完全背包、多重背包、分组背包)
    MVC 、MVP、MVVM
    java计算机毕业设计家政服务系统MyBatis+系统+LW文档+源码+调试部署
    25期代码随想录算法训练营第十天 | 栈与队列 part 1
    GitHub无法访问的解决方法
    路由的hash模式和history模式(适用于3.x版本的vue-router)
  • 原文地址:https://blog.csdn.net/m0_74357092/article/details/139592160