位置: IT常识 - 正文

动态内存的开辟(动态内存管理)

编辑:rootadmin
动态内存的开辟

推荐整理分享动态内存的开辟(动态内存管理),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:动态内存的开辟方法,动态内存申请的三个函数的原型及特点,动态内存的使用,动态内存的作用,动态内存扩展技术,动态内存的使用,动态内存的使用,动态内存的作用,内容如对您有帮助,希望把文章链接给更多的朋友!

🐶博主主页:@ᰔᩚ. 一怀明月ꦿ 

❤️‍🔥专栏系列:线性代数,C初学者入门训练,题解C,C的使用文章,「初学」C++

🔥座右铭:“不要等到什么都没有了,才下定决心去做”

🚀🚀🚀大家觉不错的话,就恳求大家点点关注,点点小爱心,指点指点🚀🚀🚀

目录

🐰动态内存管理 

🐰malloc 

🐰calloc

🐰realloc 

🐰free 

🐰动态开辟常见的错误


🐰动态内存管理 

其实我们创建数组的时候,系统为我们就是开辟了一段连续的空间(这个空间一般是在栈区开辟的),现在我们可以自己开辟一段空间。与动态开辟相关的函数:malloc free calloc realloc

注意:数组离开作用域时,系统会自动释放这段空间,如果我们自己动态开辟的空间,离开作用域时,系统是不会帮我们释放这段空间的,如果要求释放这段动态开辟的空间,我们就需要使用free函数去释放。

🐰malloc 

malloc用于动态开辟内存,引用的头文件是#include<stdlib.h>

malloc的原型:

void* malloc (size_t size);

size_t size:开辟的字节数

注意:返回的类型是void*类型,如果想要使用这段空间,就必须强制性转化为自己想使用的类型,例如:int* p=(int*)malloc(20);这就是开辟了20个字节,然后把20个字节空间的首地址赋值给了p。

malloc的使用:

malloc开辟成功会返回开辟好的空间的首地址, malloc如果申请内存失败会返回空指针NULL,所以我们开辟好空间的话,需要去判断一下

#include<stdio.h>#include<stdlib.h>#include<errno.h>#include<string.h>int main(){ int *p=(int *)malloc(20);//开辟了20个字节的空间 if(p==NULL) { printf("%s\n",strerror(errno));//打印开辟失败的原因 } free(p); p=NULL; return 0;}

 malloc开辟空间,不初始化,里面存放的随机值

#include<stdio.h>#include<stdlib.h>int main(){ int *p=(int *)malloc(20);//开辟了20个字节的空间 for(int i=0;i<5;i++) { printf("%d ",*(p+i)); } //使用 for(int i=0;i<5;i++) { *(p+i)=i+1; } for(int i=0;i<5;i++) { printf("%d ",*(p+i)); } free(p); p=NULL; return 0;}🐰calloc

calloc用于动态开辟内存,区别于malloc的是,calloc会初始化开辟的空间,将开辟的空间全部初始化为0,引用的头文件是#include<stdlib.h>

calloc的原型:

void* calloc (size_t num, size_t size);

size_t num:开辟的个数

size_t size:开辟的类型的大小

注意:返回的类型是void*类型,如果想要使用这段空间,就必须强制性转化为自己想使用的类型,例如:int* p=(int*)calloc(20,sizeof(int));这就是开辟了20个整形的空间,然后把20个整形空间的首地址赋值给了p。

calloc的使用:

 calloc开辟空间,初始化,里面存放的0

#include<stdio.h>#include<stdlib.h>int main(){ int *p=(int *)calloc(20,sizeof(int));//开辟了20个int类型的空间 for(int i=0;i<20;i++) { printf("%d ",*(p+i)); } free(p); p=NULL; return 0;}🐰realloc 

realloc用于原空间不足继续开辟更大的空间,引用头文件为#include<stdlib.h>

realloc的原型:

void* realloc (void* ptr, size_t size);动态内存的开辟(动态内存管理)

void* ptr:原空间的首地址

size_t size:开辟新空间的大小

注意:realloc开辟空间会遇到两种情况

1.如果原空间后面空间充足

在原空间后面继续开辟空间(返回的地址与原来的地址相同)

2.如果原空间后面空间不足

(1)realloc会找更大的空间

(2)将原来的数据拷贝到新空间

(3)释放原来的旧的空间

(4)返回新空间的地址(返回的地址与原来的地址不同)

realloc的使用:

#include<stdio.h>#include<stdlib.h>#include<string.h>#include<errno.h>int main(){ int *p=(int *)malloc(20);//开辟了20个int类型的空间 if(p==NULL) { printf("%s\n",strerror(errno)); } for(int i=0;i<5;i++) { printf("%d ",*(p+i)); } int* pc=(int*)realloc(p,sizeof(p)*2);//在原空间进行扩展 if(pc!=NULL) { p=pc;//把空间首地址还是赋给p for(int i=0;i<10;i++) { printf("%d ",*(p+i)); } } else { printf("realloc:%s\n",strerror(errno));//如果开辟失败,打印原因 } free(p); p=NULL; return 0;}🐰free 

free用于释放动态开辟的空间,引用头文件#include<stdlib.h>

free的原型:

void free (void* ptr);

void* ptr:动态开辟空间的首地址

注意:释放的空间一定是动态开辟的(就是在堆上开辟的),不然free是不起作用的。

 free的使用:

#include<stdio.h>#include<stdlib.h>int main(){ int* p=(int *)malloc(20);//开辟了20个字节的空间 free(p);//将20个字节的空间还给了系统 p=NULL;//如果不把p置为空指针,那么p就是野指针 return 0;}🐰动态开辟常见的错误

可能开辟空间失败,然后再去解引用会发生错误,所以malloc的返回值要去判断和越界访问。

#include<stdio.h>#include<stdlib.h>#include<string.h>#include<errno.h>int main(){ int* p=(int*)malloc(20); //可能开辟空间失败,然后再去解引用会发生错误,所以malloc的返回值要去判断 //所以我们需要判断 if(p==NULL) { printf("%s",strerror(errno));//打印发生的错误 return; } for(int i=0;i<5;i++) { p[i]=i; } //越界访问 for(int i=0;i<10;i++)//只开辟了5个int类型的空间,却访问了10个int类型的空间 { p[i]=i; } free(p); p=NULL; return 0;}

对非动态开辟的空间进行释放

#include<stdio.h>#include<stdlib.h>int main(){ int arr[10]={1,2,3}; int *p=arr; free(p);//对非动态开辟的空间进行释放 return 0;}

释放一部分动态开辟的空间

#include<stdio.h>#include<stdlib.h>int main(){ int* p=(int*)malloc(40); for(int i=0;i<10;i++) { p[i]=i; } p++;//p指向的就不是动态开辟空间的首地址 free(p);//使用free释放一块动态开辟内存的一部分,不是从开辟空间的首地址开始释放的 p=NULL; return 0;}

对一块空间多次释放

#include<stdio.h>#include<stdlib.h>int main(){ int* p=(int*)malloc(40); free(p); //p=NULL;//如果释放了指针之后,再次释放是不会出错的,因为指针为空时,free不会做出任何反应 free(p);//重复释放 p=NULL; return 0;}

不能对空指针进行解引用操作

#include<stdio.h>#include<string.h>#include<stdlib.h>void GetMemory(char* str){ str=(char *)malloc(20); //str是p的临时拷贝,malloc动态开辟的空间,将首地址给了str,p仍然是空指针}int main(){ char* p=NULL; GetMemory(p); strcpy(p,"hello world");//这里对空指针进行了解引用操作 printf("%s",p); return 0;}

野指针问题

#include<stdio.h>#include<string.h>#include<stdlib.h>char* GetMemory(void){ char str[]="hello world"; //返回栈区空间的问题 //GetMemory函数内部创建的数组str,str是临时创建,虽然返回了str数组的首地址,但是离开GetMemory函数之后,str内存会归还给系统,p的值虽然还是str数组的首地址,但是str空间已经归还给系统,str再去访问就是非法访问了。(栈区开辟的空间,离开作用域,栈区开辟的空间会被销毁) return str;}int main(){ char* p=NULL; p=GetMemory(); printf("%s",p); return 0;}

注:一定要记住

栈区:局部变量,函数形参

堆区:动态管理的空间(malloc,realloc,calloc,free)

静态区:静态变量,全局变量

 🌸🌸🌸如果大家还有不懂或者建议都可以发在评论区,我们共同探讨,共同学习,共同进步。谢谢大家! 🌸🌸🌸 

本文链接地址:https://www.jiuchutong.com/zhishi/299517.html 转载请保留说明!

上一篇:SpringBoot+Vue实现在线商城系统

下一篇:「Vue面试题」在项目中你是如何解决跨域的?(vue的常见面试题)

  • 注册网赚要注意的问题(网络注册赚钱是真的吗)

    注册网赚要注意的问题(网络注册赚钱是真的吗)

  • 黑鲨4spro怎么开nfc(黑鲨四怎么开启游戏模式)

    黑鲨4spro怎么开nfc(黑鲨四怎么开启游戏模式)

  • 抖音有提词器功能吗(抖音提词器有什么用)

    抖音有提词器功能吗(抖音提词器有什么用)

  • 苹果13面部解锁后怎么直接进入桌面(苹果13面部解锁怎么设置)

    苹果13面部解锁后怎么直接进入桌面(苹果13面部解锁怎么设置)

  • ac24v与dc24v区别(ac24v和dc24v能混用吗)

    ac24v与dc24v区别(ac24v和dc24v能混用吗)

  • 微信怎么能更改微信号(微信怎么能更改好友头像)

    微信怎么能更改微信号(微信怎么能更改好友头像)

  • 电脑主板坏了值得修吗(电脑主板坏了难修吗)

    电脑主板坏了值得修吗(电脑主板坏了难修吗)

  • 电脑显示证书过期怎么回事(电脑显示证书过期或未生效)

    电脑显示证书过期怎么回事(电脑显示证书过期或未生效)

  • 苹果11闪退自动关机(苹果闪退自动关机怎么回事)

    苹果11闪退自动关机(苹果闪退自动关机怎么回事)

  • 发光二极管是什么导体(发光二极管是什么能转化为什么能)

    发光二极管是什么导体(发光二极管是什么能转化为什么能)

  • 我的微信置顶语别人能看到吗(微信置顶语设置)

    我的微信置顶语别人能看到吗(微信置顶语设置)

  • xr来电不显示名字(xr来电不显示名称怎么办)

    xr来电不显示名字(xr来电不显示名称怎么办)

  • 手机一拔掉充电器就关机怎么回事(手机一拔掉充电器就重启怎么回事)

    手机一拔掉充电器就关机怎么回事(手机一拔掉充电器就重启怎么回事)

  • 腾讯课堂老师可以看学生的摄像头吗(腾讯课堂老师可以看到学生分屏在干什么吗)

    腾讯课堂老师可以看学生的摄像头吗(腾讯课堂老师可以看到学生分屏在干什么吗)

  • xsmax是英特尔基带吗(苹果xsmax是不是都是英特尔基带)

    xsmax是英特尔基带吗(苹果xsmax是不是都是英特尔基带)

  • 淘宝天猫积分什么时候清零(淘宝 天猫积分)

    淘宝天猫积分什么时候清零(淘宝 天猫积分)

  • 手机左边的按键是什么(手机左边的按键按不了怎么办)

    手机左边的按键是什么(手机左边的按键按不了怎么办)

  • 苹果11pro有刘海吗(苹果11pro有没有刘海)

    苹果11pro有刘海吗(苹果11pro有没有刘海)

  • 嘀嗒乘客不点确认到达多久到账(嘀嗒乘客不点确认到达)

    嘀嗒乘客不点确认到达多久到账(嘀嗒乘客不点确认到达)

  • 采用虚拟存储器的原因(采用虚拟存储器的目的)

    采用虚拟存储器的原因(采用虚拟存储器的目的)

  • 惠普2678打印机怎么连接无线网(惠普2678打印机如何连接手机)

    惠普2678打印机怎么连接无线网(惠普2678打印机如何连接手机)

  • qq感兴趣的群怎么删掉(qq感兴趣的群怎么找)

    qq感兴趣的群怎么删掉(qq感兴趣的群怎么找)

  • iphone7隔空投送在哪里(iphone7隔空投送用不了怎么回事)

    iphone7隔空投送在哪里(iphone7隔空投送用不了怎么回事)

  • airpods零售店能刻字吗(零售店买的airpods可以退货吗)

    airpods零售店能刻字吗(零售店买的airpods可以退货吗)

  • 京东好店和京东自营有什么区别(京东好店和京东自营哪个好)

    京东好店和京东自营有什么区别(京东好店和京东自营哪个好)

  • Vue中实现自定义excel下载(vue自定义dialog)

    Vue中实现自定义excel下载(vue自定义dialog)

  • 研发费用加计扣除是什么意思啊
  • 其他应付款转实收资本有风险吗
  • 发生额对照表
  • 利润表年底净利润是正数吗
  • 分公司企业所得税汇总缴纳还是单独缴纳
  • 车间用的电线计入什么科目
  • 房地产公司环境
  • 安全费用中的固定资产如何写会计分录?
  • 预缴增值税为什么记借方
  • 保证金抵扣货款合同
  • 现金支票作废需要签字吗
  • 企业发票入账冲销流程
  • 工资手续费可以在发放里扣除吗
  • 公益捐赠税前扣除凭证
  • 怎么去税务局申报个税
  • 卷式增值税发票校验码怎么查
  • 增值税零申报,企业所得税会有税额吗
  • 特许权使用费怎么入账
  • 纳税人如何办理纳税申报
  • 个税手续费需要开具发票吗
  • 外商投资企业补税政策
  • 固定资产清理账户期末有余额吗
  • 出口退税企业的税负率怎么算?
  • 民间非营利组织会计制度最新版
  • windows10如何清理c盘垃圾
  • 主营业务成本算损益类科目吗
  • 贷款逾期了利息和罚息可以不还吗
  • 华为p50新款
  • thinkphp limit
  • 驾校收入与成本的关系
  • php面向对象优点,缺点
  • 科普笔记本电脑怎样
  • php字符串赋值
  • 包装破损导致物品损坏
  • 为什么磁盘会消失
  • 政府性基金收入怎么收
  • 合伙搞养殖
  • 蒙塔巴诺督查
  • jQuery dom操作
  • 关系抽取系统的要求
  • ChatGPT火爆来袭,携手参与为开源助力
  • vget命令
  • 林场苗圃工作有哪些
  • 帝国主义
  • java第一步
  • 收入和成本的原则是什么
  • 城建税小规模纳税人
  • 出纳开的收据找不到了怎么办
  • sqlserver去掉字符串内的指定字符
  • 个人独资企业的
  • 服务费可以计入主营业务成本吗
  • 合并企业如何缴纳印花税
  • 公司注销后如何起诉他人
  • 农产品加计扣除怎么计算
  • 应付职工薪酬为负数什么意思
  • 租赁财产的残值处理
  • 原材料暂估入库成本结转处理
  • 会计常用表格都有哪些技能
  • mysql单表10亿
  • win8更新到win8.1
  • vmware8.0.4
  • xp操作系统还能用吗
  • WIN7系统如何设置自动关机
  • windows传输到mac
  • centos 7安装教程(图文详解)
  • 重装win7系统后屏幕变小了
  • linux服务器日志文件在哪里
  • cocos creator 优化 drawcall 合并
  • perl数组元素个数
  • 实用的批处理命令
  • django forloop
  • nodejs怎么实现多线程
  • unity3d官方
  • nodejs搭建网站
  • JavaScript Break 和 Continue区别教程
  • 重新加载activity
  • 税务局营改增文件
  • 支付宝怎么样开通刷脸支付
  • 天津2020年契税征收标准
  • 社保当月减员当月还可以增加上吗
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设