位置: 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的常见面试题)

  • 快手不知道名字和id怎么找人(快手不知道名字怎么改)

    快手不知道名字和id怎么找人(快手不知道名字怎么改)

  • qq画画红包怎么识别(qq画画红包多来a梦)

    qq画画红包怎么识别(qq画画红包多来a梦)

  • 怎么看微信是否在电脑上登录(怎么看微信是否被屏蔽)

    怎么看微信是否在电脑上登录(怎么看微信是否被屏蔽)

  • 华为p30pro内存卡插什么地方(华为p30pro内存卡不显示)

    华为p30pro内存卡插什么地方(华为p30pro内存卡不显示)

  • 手机端h5是什么意思(手机h5页面是什么)

    手机端h5是什么意思(手机h5页面是什么)

  • 微信签名为什么改不了(微信签名为什么只能写30个字)

    微信签名为什么改不了(微信签名为什么只能写30个字)

  • 抖音举报评论的时候会不会被对方发现(抖音举报评论的理由100字)

    抖音举报评论的时候会不会被对方发现(抖音举报评论的理由100字)

  • 短信删了对方还显示吗(短信删了对方还能收到吗)

    短信删了对方还显示吗(短信删了对方还能收到吗)

  • 怎么让网易云音乐显示在通知栏(怎么让网易云音乐不被打断)

    怎么让网易云音乐显示在通知栏(怎么让网易云音乐不被打断)

  • app内购买项目要付费吗(app内购买项目要交税吗)

    app内购买项目要付费吗(app内购买项目要交税吗)

  • 手机查看淘宝开店时间(手机淘宝在哪里看自己开的店铺)

    手机查看淘宝开店时间(手机淘宝在哪里看自己开的店铺)

  • 华为手机如何设置应用使用时间(华为手机如何设置返回键)

    华为手机如何设置应用使用时间(华为手机如何设置返回键)

  • 荣耀20pro是4天线吗(荣耀20是单天线还是双天线)

    荣耀20pro是4天线吗(荣耀20是单天线还是双天线)

  • 抖音已重置怎么恢复(抖音重置怎么弄)

    抖音已重置怎么恢复(抖音重置怎么弄)

  • 手机wadl文件能删除吗(手机文件tmsdual)

    手机wadl文件能删除吗(手机文件tmsdual)

  • 快手复制链接怎么上传(快手复制链接怎么打开)

    快手复制链接怎么上传(快手复制链接怎么打开)

  • 淘宝商店怎样注册(淘宝商店怎样注销)

    淘宝商店怎样注册(淘宝商店怎样注销)

  • 小米手机不能安装微信(小米手机不能安装巅峰极速)

    小米手机不能安装微信(小米手机不能安装巅峰极速)

  • iqooneo支持内存卡吗(iqooneo3支持内存卡扩展吗)

    iqooneo支持内存卡吗(iqooneo3支持内存卡扩展吗)

  • qq音乐专辑铭牌在哪里(qq音乐专辑铭牌怎么看)

    qq音乐专辑铭牌在哪里(qq音乐专辑铭牌怎么看)

  • 安卓手机怎么打印照片(安卓手机怎么打开定位)

    安卓手机怎么打印照片(安卓手机怎么打开定位)

  • 手机怎么踢出wifi蹭网(手机怎么踢出wifi蹭网华为)

    手机怎么踢出wifi蹭网(手机怎么踢出wifi蹭网华为)

  • ipad美版和国行的区别(iPad美版和国行的充电器一样吗)

    ipad美版和国行的区别(iPad美版和国行的充电器一样吗)

  • shiftf5是什么快捷键

    shiftf5是什么快捷键

  • excel怎样增加单元格(excel表怎么增加单元格)

    excel怎样增加单元格(excel表怎么增加单元格)

  • 什么协议是提供不可靠的数据传输(什么协议是提供服务的)

    什么协议是提供不可靠的数据传输(什么协议是提供服务的)

  • excel银行卡号格式(excel输入银行卡号格式)

    excel银行卡号格式(excel输入银行卡号格式)

  • 帝国cms灵动标签里的序号如何实现(帝国cms灵动标签排除上一篇下一篇文章)

    帝国cms灵动标签里的序号如何实现(帝国cms灵动标签排除上一篇下一篇文章)

  • 企业的筹建期允许有多长?
  • 报销单的经办人写自己吗
  • 打包材料的费用会计分录
  • 出口退税逾期申报,需申报出口货物收汇情况表
  • 账本一般保存几年就可以销毁2004年的规定
  • 自行建造固定资产中的自营工程,在领用工程物资
  • 自建办公楼销售要交土地增值税吗
  • 收到总公司投资款怎么做账务处理
  • 筹建期的印花税计入现金流量表哪里
  • 报关单不存在
  • 出口的进项发票如何记账
  • 返利失效了怎么找回
  • 餐费专票认证了怎么办
  • 个人在电商平台购买跨境商品需要缴纳什么税
  • 建筑公司亏损异常怎么办
  • 纳税主要是哪些方面
  • 电子承兑汇票接收时间是多久
  • 会计调账必须写说明吗
  • 每个月的股利怎么计提?
  • mac安装软件提示身份不明
  • 小公司做帐
  • 印花税的征收范围
  • 企业所得税申报表
  • 暂存款借方余额
  • linux 去除换行
  • 承租人对经营租赁的会计处,怎么快速记住方法
  • PHP:pg_get_pid()的用法_PostgreSQL函数
  • 什么是坏账,坏账的核算方法有哪些
  • 解决方案啥意思
  • php数组可以使用哪些键名
  • 结转成本类账户到本年利润的会计分录
  • 员工出差垫钱
  • win10系统安装配置
  • pip清华源安装
  • 个税申报系统操作指南
  • 图片防止侵权怎么写
  • nlp自然语言处理框架
  • python函数的默认值
  • python 嵌入
  • 上个月发票税率怎么查
  • 咨询服务费怎么交税
  • 映射器可以定义参数类型
  • sqlserver数据库锁表如何解锁
  • 社保所属期怎么填
  • 材料采购账户的借方登记什么
  • 建筑企业异地施工预缴企业所得税
  • mysql默认值怎么设置
  • 银行对账单电脑上怎么导出
  • 印花税实际缴纳时计入
  • 一般纳税人简易计税方法适用情形
  • 应收账款管理应该收集哪些信息
  • 外账需要计提存利息吗
  • 期末应交税费有余额吗
  • 农产品加计扣除1%怎么计算和会计分录
  • 管理成本分摊比例是多少
  • 未开票收入怎么报税
  • 银行承兑汇票记载事项
  • 银行凭证怎么记账
  • 建账的依据是什么
  • sql语句错误提示
  • sql server索引的使用
  • 如何删除多余的空白表格
  • xp系统删除文件反应很慢
  • centos如何删除用户组里面的用户
  • windows7计算机管理拒绝访问
  • win7怎么设置禁止安装软件
  • 如何设置自动删除安装包
  • 淘宝win10和正版的有什么区别
  • windows免费升级win10
  • windows7睡眠唤醒快捷键
  • 查找linux
  • jquery设置鼠标样式
  • pycharm官方教程
  • 去掉字符串中的某个值
  • shell脚本识别十六进制数
  • Python工程师面试题 与Python Web相关
  • js jquery区别
  • 小规模企业所得税怎么算
  • 深圳12366接听客服工作怎么样
  • 山东国税局官网登录
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

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

    友情链接: 武汉网站建设