为什么存在动态内存分配,动态内存函数(malloc函数,free函数,calloc函数,realloc函数)...

点击蓝字

659fca768323293312cca67da89ab1cd.png

关注我们

1.当前我们知道的内存的使用方法

5ed9c6eab079ef066f7320f1be817eea.png

2.为什么存在动态内存分配

如上我们已学的开辟空间的方式有两个特点:

  • 空间开辟的大小是固定的

  • 必须指定数组的长度

所以就产生了空间开大了浪费开小了不够用的问题,所以使用动态内存分配

3.动态内存函数

(1)malloc 和 free

a.malloc函数

d6bc2d54dbda1a2f013f771040176244.png

malloc函数向内存申请一块连续可用的空间,并返回指向这块空间的指针。

  • 如果开辟成功,返回一个指向开辟好空间的指针

  • 如果开辟失败,返回一个NULL指针,因此malloc的返回值一定要做检查

b. free函数

9c846d05852b86146593e2b5268b8d0d.png

free函数用来释放动态开辟的内存

  • 如果参数p指向的空间不是动态开辟的(eg:数组),那free函数的行为是未定义的;

  • 如果参数p是NULL指针,则函数什么事都不用做;

c.举例说明malloc函数和free函数如何使用

  •  开辟10个整形大小的空间,并将0-9放入

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{//向内存申请10个整形的空间int* p = (int*)malloc(10 * sizeof(int));//开辟空间失败,打印失败原因if (p == NULL){//errno:Last error numberprintf("%s\n", strerror(errno));}//开辟空间成功,将0-9放入else{for (int i = 0; i < 10; i++){*(p + i) = i;}for (int i = 0; i < 10; i++){printf("%d ", *(p + i));}}//释放掉p指向的这段空间,但是指针p还是指向这段空间free(p);//防止野指针,需要将指针制空p = NULL;return 0;
}

输出:

b3481505932cf7ff7c02a32750fed941.png

  • 开辟空间失败,并打印开辟失败原因

 INT_MAX 整形最大–>可右键转到定义查看
bf142e10a94c8cadbc48dd079988ae96.png

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{//向内存申请10个整形的空间int* p = (int*)malloc(INT_MAX);//开辟空间失败,打印失败原因if (p == NULL){//errno:Last error numberprintf("%s\n", strerror(errno));}//开辟空间成功,将0-9放入else{for (int i = 0; i < 10; i++){*(p + i) = i;}for (int i = 0; i < 10; i++){printf("%d ", *(p + i));}}//释放掉p指向的这段空间,但是指针p还是指向这段空间free(p);//防止野指针,需要将指针制空p = NULL;return 0;
}

6143e5fbef42d07a9e74cd968315e3a5.png

(2)calloc

a. calloc函数

9539e6b47d15ed90ed0f7eb79c397d9d.png

  • calloc函数的功能是为num个大小为size的元素开辟一块空间,并且把空间的每个字节初始化为0

  • calloc和malloc的区别在于calloc会在返回地址之前把申请的空间的每个字节初始化为0

b.举例说明calloc函数如何使用

  • 开辟10个整形大小的空间并初始化为0

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
int main()
{int* p = (int*)calloc(10, sizeof(int));if (p == NULL){printf("%s\n", strerror(errno));}else{for (int i = 0; i < 10; i++){printf("%d ", *(p + i));}}free(p);p = NULL;return 0;
}

467aed2c1b1367917170e1aa564b9f4d.png

37ac4960ce663b924ad283d855a513c9.png

(3)realloc

a. realloc函数

f55975d089bc3fb707ddbcd3ef144de5.png

  • p是要调整的内存地址

  • size是调整之后的大小

  • 返回值为调整之后的内存起始位置

b.realloc在调整内存空间存在的两种情况:

 情况1:原有空间之后有足够大的空间

如果p指向的空间之后有足够的内存空间可以追加,则直接追加,然后返回p

152fa90491998d5d22c66b54f34affc2.png

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main()
{int* p = (int*)malloc(20);if (p == NULL){printf("%s\n", strerror(errno));}else{for (int i = 0; i < 5; i++){*(p + i) = i;}}//得用一个新的变量来接受realloc函数的返回值//防止开辟失败返回NULL给p找不到之前的空间int*ptr = (int*)realloc(p,40);if (ptr != NULL){p = ptr;for (int i = 5; i < 10; i++){*(p + i) = i;}for (int i = 0; i < 10; i++){printf("%d ", *(p + i));}}free(p);p = NULL;return 0;
}

f51ef24235249776f60c77650f836c06.png

c9e16b3d61556cd769a9961c8f653c2e.png

情况2:原有空间之后没有足够大的空间

如果p指向的空间之后没有足够大的内存空间可以追加,则realloc函数会重新找一块新的内存区域,开辟一块满足需求的空间,并把原来内存中的数据拷贝到新的空间,释放旧的内存空间,最后返回新开辟的内存空间地址

776291f27eb993fba501ba20e8053281.png

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int main()
{int* p = (int*)malloc(20);if (p == NULL){printf("%s\n", strerror(errno));}else{for (int i = 0; i < 5; i++){*(p + i) = i;}}//得用一个新的变量来接受realloc函数的返回值//防止开辟失败返回NULL给p找不到之前的空间int*ptr = (int*)realloc(p,4000);if (ptr != NULL){p = ptr;for (int i = 5; i < 10; i++){*(p + i) = i;}for (int i = 0; i < 10; i++){printf("%d ", *(p + i));}}free(p);p = NULL;return 0;
}

33f5d8379699531f695b1bb52df30834.png

773c5616b7601a327266da52a6f0ef1c.png

注意:得用一个新的变量来接受realloc函数的返回值,防止开辟失败返回NULL给p找不到之前的空间

7fd67ba02f2335dac9bb92301ef0cc85.gif

如果你年满18周岁以上,又觉得学【C语言】太难?想尝试其他编程语言,那么我推荐你学Python,现有价值499元Python零基础课程限时免费领取,限10个名额!
▲扫描二维码-免费领取

70047d1affd9f666aacdba3da98bee45.gif

戳“阅读原文”我们一起进步

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/337392.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

论游戏项目中的左与右

标题《论游戏项目中的左与右》 何为左与右&#xff1f;左&#xff0c;左倾&#xff0c;即 激进主义&#xff0c;冒险主义&#xff0c;盲动主义。右&#xff0c;右倾&#xff0c;即 消极主义&#xff0c;保守主义&#xff0c;投降主义。 &#xff08;一&#xff09;先说说关于…

java处理注释_Java注释处理器

java处理注释本文是我们名为“ 高级Java ”的学院课程的一部分。 本课程旨在帮助您最有效地使用Java。 它讨论了高级主题&#xff0c;包括对象创建&#xff0c;并发&#xff0c;序列化&#xff0c;反射等。 它将指导您完成Java掌握的旅程&#xff01; 在这里查看 &#xff01;…

C++ vector类的模拟实现

点击蓝字关注我们1.前言vector和string虽然底层都是通过顺序表来实现的&#xff0c;但是他们利用顺序表的方式不同&#xff0c;string是指定好了类型&#xff0c;通过使用顺序表来存储并对数据进行操作&#xff0c;而vector是利用了C中的泛型模板&#xff0c;可以存储任何类型的…

visual studio源文件的编译顺序是依据什么?

问题&#xff1a;visual studio源文件的编译顺序是依据什么&#xff1f; 结论&#xff1a;依据 .vcxproj 文件里 指定了ClCompile的ItemGroup &#xff0c;如下图所示&#xff0c;就是这么简单粗暴。

并发运行的最佳实践_并发最佳实践

并发运行的最佳实践本文是我们名为“ 高级Java ”的学院课程的一部分。 本课程旨在帮助您最有效地使用Java。 它讨论了高级主题&#xff0c;包括对象创建&#xff0c;并发&#xff0c;序列化&#xff0c;反射等。 它将指导您完成Java掌握的旅程&#xff01; 在这里查看 &#…

功能齐全的屏幕截图C++实现详解

点击蓝字关注我们1、概述要使用屏幕截图&#xff0c;其实很容易&#xff0c;装一款聊天软件或者办公软件就可以了&#xff0c;比如QQ、企业微信、钉钉、飞书等。但要开发出类似这些软件的屏幕截图模块&#xff0c;则没那么容易。其实实现屏幕截图的技术并不复杂&#xff0c;主要…

如何判断exe文件是debug还是release编译生成的

如何判断exe文件是debug还是release编译生成的结论&#xff1a; 用IDA工具打开exe&#xff0c;然后看Imports里面的依赖库是否有带d或D结尾的&#xff0c;如果有就说明是Debug的 实验&#xff1a;&#xff08;实验环境 vs2017&#xff0c; IDA工具&#xff09; &#xff08;0&…

大屏可视化分配率是什么意思_什么是分配率?

大屏可视化分配率是什么意思诸如“不可持续的分配率”和“您需要保持较低的分配率”之类的短语似乎仅属于Java Champions的词汇表。 复杂&#xff0c;恐怖并被魔术光环包围。 经常发生的情况是&#xff0c;当您更仔细地查看概念时&#xff0c;魔术会随着抽烟消失。 这篇文章试…

C/C++语言动态开辟的杨辉三角

点击蓝字关注我们问题引入杨辉三角相必大家并不陌生&#xff0c;第1行有1列、第二行有2列…第n行有n列&#xff0c;且每行行首和行尾的值都为1&#xff0c;其余的值为上一行两数相加我们在C语言阶段&#xff0c;第一次碰到的杨辉三角应该都是用常规的二维数组存储&#xff0c;可…

git gui 历史版本_这些Git命令都不会,还是不要去面试了

前言以下&#xff0c;项目中经常使用的Git命令&#xff0c;汇总到这里以便与你能快速的学习和掌握Git命令&#xff0c;在文章最后有惊喜哟&#xff0c;一定要看到最后啊&#xff01;使用的 Git版本&#xff1a;git version 2.24.0命令git log# 输出概要日志,这条命令等同于# gi…

java restful_Java EE中的RESTful计时器

java restful在这篇文章中...。 EJB计时器旋风之旅 通过带有示例实现的简单REST接口即时使用EJB计时器 更新&#xff08;2015年7月14日&#xff09; 该应用程序的前端现在可以在OpenShift上使用 。 由于我是前端新手&#xff0c;因此我在其他来源的帮助下组装了此HTML5 Ang…

【lua学习】1.源码组织

虚拟机核心相关文件列表内嵌库相关文件解释器&#xff0c;字节码编译器相关的文件做cocos2d-x lua已经有一段时间了&#xff0c;想更深入了解lua。我会出一系列地 自身学习过程中地解读。我会带大家沿着源码来逐步解读lua&#xff0c;我喜欢按照 深度优先遍历的顺序来解读源码&…

c# 联合halcon 基于相关性 模板匹配_机器视觉之halcon入门(5)-字符识别exe生成...

2.3.2 第二个halcon程序转EXE程序&#xff1a;字符识别老规矩&#xff0c;每一段halcon代码得用C#二次开发下。根据上一节所教的&#xff0c;我们配置下C#的环境&#xff0c;顺便添加好控件&#xff0c;如下图(2-3-2-1)。图 2-3-2-1控件基本跟上一节一样&#xff0c;只是少了一…

C语言数据的存储和取出(超详细讲解)

点击蓝字关注我们整形的储存我们知道一个整形的存储是以补码的形式储存取出是原码的形式。比如&#xff1a;int a 5;的二进制是101那它的原码应该是&#xff1a;00000000 00000000 00000000 00000101正数的原反补相同那它存进去和取出来都是&#xff1a;00000000 00000000 000…

go语言 不支持动态加载_动态语言支持

go语言 不支持动态加载本文是我们名为“ 高级Java ”的学院课程的一部分。 本课程旨在帮助您最有效地使用Java。 它讨论了高级主题&#xff0c;包括对象创建&#xff0c;并发&#xff0c;序列化&#xff0c;反射等。 它将指导您完成Java掌握的旅程&#xff01; 在这里查看 &am…

【lua学习】2.数据类型

【lua学习】2.数据类型Lua中的数据类型关于TValue自顶向下分析TValue表示所有的Lua数据结构并带一个类型字段Value表示所有的Lua数据结构GCObject表示所有需要进行垃圾回收的数据结构GCheader表示需要GC的数据结构最开始的部分Lua中的数据类型 宏名 (见lua.h)宏值类型对应数据…

打印pdf就一页_PDF 文件转换工具

是将 PDF 文件转换为完全可编辑的 Windows 文档最好的转换软件。无论您需要您的内容是 Microsoft Word、Excel、PowerPoint、HTML 还是仅需要文本&#xff0c; 总会给您一个简单的方法&#xff0c;快捷地获取您要的内容。可转换整个文档或选择内容。亦可创建 PDF 文件。PDF 转换…

C++类的this指针,静态成员,友元函数友元类

点击蓝字关注我们1. this指针在上篇讲C中类&#xff0c;对象&#xff0c;封装&#xff0c;继承&#xff08;派生&#xff09;&#xff0c;多态的时候&#xff0c;this指针出现在成员函数中&#xff0c;并使用->成员提取符操作成员变量。在 C 中&#xff0c;每一个对象都能通…

jooq和jdbc_将jOOQ与JDBC比较

jooq和jdbc本文是我们学院课程“ jOOQ –类型安全数据库查询”的一部分 。 在SQL和特定关系数据库很重要的Java应用程序中&#xff0c;jOOQ是一个不错的选择。 当JPA / Hibernate抽象过多而JDBC过于抽象时&#xff0c;这是一种替代方法。 它显示了一种现代的领域特定语言如何可…

【lua学习】3.字符串

【lua学习】3.字符串Lua字符串的概况字符串实现字符串结构TString全局字符串表stringtable新建字符串luaS_newlstr &#xff08;先查表&#xff0c;再决定创建与否&#xff09;新建字符串 newlstr重新设置全局字符串的大小 luaS_resize全局字符串表的缩容保留字是如何不被回收的…