【动态内存】C语言动态内存使用常见错误及其避免方法(初学者避雷)
C语言动态内存使用常见错误及其避免方法(初学者动态内存避雷手册)
求个赞求个赞求个赞求个赞 谢谢
先赞后看好习惯 打字不容易,这都是很用心做的,希望得到支持你 大家的点赞和支持对于我来说是一种非常重要的动力 看完之后别忘记关注我哦!️️️
动态内存开辟常见错误
1.对NULL指针的解引用
2.越界访问
3.使用free释放非动态开辟的空间
4.使用free释放动态内存中的一部分
5.对同一块动态开辟的空间,多次释放
6.动态开辟的空间忘记释放-比较严重
文章目录
对空指针的非法解引用
一般来说,有一定基础的我们都不会故意解引用空指针,但是,我们在使用动态内存开辟的时候,可能会解引用到”无形“的空指针
int main()
{
int*p=(int*)malloc(10000000000000000000);
int i = 0;
for (i = 0; i < 10; i++)
{
*(p + i) = i;//err
}
return 0;
}
在上面这个代码中,看似没有什么问题。但是我们知道malloc函数是有可能开辟动态内存空间失败的,我们一口气开辟这么多字节的空间,我们堆上空间不够用了,malloc函数就会开辟失败,我们通过www.cplusplus.com网站搜索malloc函数我们可以知道,如果函数开辟失败,会返回空指针,那么这个时候,我们的p就是一个空指针,空指针怎么能解引用呢?
我们可以在for之前用一个perror()函数来查看我们的问题perror("main:");

为了避免在编写程序的时候遇到这个问题,我们可以用assert()断言后再使用该指针,或者使用if语句,当指针为真的时候再使用该指针
越界访问问题
int main()
{
int* p = (int*)malloc(10 * sizeof(int));
if (p == NULL)
{
return 1;
}
int i = 0;
//越界访问,我们只开辟了40个字节,不是四十个整型
for (i = 0; i < 40; i++)
{
*(p + i) = i;
}
free(p);
p = NULL;
return 0;
}
正如这个代码,我们必须知道malloc函数在堆上开辟的时候的单位是字节,而我们这里却要访问40个整型,也就是160个字节,这就越界访问了
每写一步我们思考清楚就可以避免这个问题。
使用free释放非动态开辟的空间
free只能用来释放堆上的动态开辟的空间,而不能释放栈上的空间,栈上的内存空间,在函数结束,程序结束都会自动释放的。
//3.使用free释放非动态开辟的空间
int main()
{
int arr[10] = { 0 };
int* p = arr;
free(p);//err
p = NULL;
return 0;
}
每写一步我们思考清楚就可以避免这个问题。
使用free释放动态内存中的一部分
释放了,但没完全释放
//4.使用free释放动态内存中的一部分
int main()
{
int* p = malloc(10 * sizeof(int));
if (p == NULL)
{
return 1;
}
int i = 0;
for (i = 0; i < 5; i++)
{
*p++ = i;//我的p不见了
}
free(p);//err
p = NULL;
return 0;
}
*在这个代码中,由p指针指向的动态内存开辟后,我们的p在后续操作中改变了它自己的值,这意味这什么?
这代表没东西再可以找到这块空间了,我们到时候free§只是free()掉了p后面的一些空间,那么p前面的空间呢?不管了?
所以如果p这个位置改变了,找不到了是一件很可怕的事情。
那么,我们如何避免呢?
如果在后续我们要操作p,我们一开始就要用另一个的指针变量来记录我一开始p的位置,最后free()这个记录起始位置的指针变量,这样就可以避免“free()了,但没完全free()的问题”
对同一块动态开辟的空间,多次释放的问题
//5.对同一块动态开辟的空间,多次释放
int main()
{
int* p = (int*)malloc(100);
//使用
//...
free(p);//万一一个在函数里面,没发现,就会出现这种情况
//
free(p);
return 0;
//所以这个时候,我们需要再free完,立刻把p置为空指针
//这样的话,第二次调用free()的时候,传空指针,什么事情都不会发生
}
看到这里,有些伙伴可能会问:我肯定不会两个free写在一起啊
这里其实只是比较明显而已,如果在函数里面,已经free了,后面又写了很多代码,最后想起来又free一次,这样就会出现这种问题了
为了避免这个问题,我们一定要主动地在free()之后,马上把我们的p置空:p=NULL;这样我们后面就算在free(),free()函数传NULL给它的时候,是不会有任何问题的。
动态开辟的空间忘记释放(比较严重的问题)
//6.动态开辟的空间忘记释放
void test()
{
int* p = (int*)malloc(100);
if (p == NULL)
{
return;
}
//使用
//忘记释放了
//
//
//
//当我们出函数的时候,p会自动释放,那没人可以找到那块在堆上的空间了
//如果return以后,就没有人可以找到p指向的空间了
//这样会造成内存泄露
}
int main()
{
test();
return 0;
}
我们在前面介绍部分释放这个问题的时候已经知道,不free()会造成内存泄漏
在这里,我来为大家总结一下堆上动态开辟的空间的两种释放方式
1.程序员代码主动释放,即调用free()函数
2.程序结束
在我们一开始使用动态内存的阶段,这个问题可能看似没那么严重,程序好像照样跑,反正泄露一点也没关系,程序结束它就自动释放了
但如果我们这是一个服务器的程序呢,24小时跑呢,假如内存只有32个g,每天泄露一点,那机器不就越来越卡了?,最后只会卡死,卡死了就重启,又卡死,再重启。这种问题就会对我们的机器的使用造成很大困扰。所以内存泄漏其实是一个比较严重的问题,所以我们一定要记得free().
尾声
看到这里,相信你对动态内存使用的一些雷区有了更深的了解,也相信你已经学会了避免这些问题的方法。
如果你感觉这期博客对你帮助的话,别忘了转发,收藏,点赞,关注,一波四连再走哦!
【动态内存】C语言动态内存使用常见错误及其避免方法(初学者避雷)的更多相关文章
- 深入理解C语言 - 指针使用的常见错误
在C语言中,指针的重要性不言而喻,但在很多时候指针又被认为是一把双刃剑.一方面,指针是构建数据结构和操作内存的精确而高效的工具.另一方面,它们又很容易误用,从而产生不可预知的软件bug.下面总结一下指 ...
- R语言编程中的常见错误
R语言编程中的常见错误有一些错误是R的初学者和经验丰富的R程序员都可能常犯的.如果程序出错了,请检查以下几方面. 使用了错误的大小写.help().Help()和HELP()是三个不同的函数(只有第 ...
- 微信jssdk常见错误及解决方法
调用config 接口的时候传入参数 debug: true 可以开启debug模式,页面会alert出错误信息.以下为常见错误及解决方法: invalid url domain当前页面所在域名与使用 ...
- WCF项目中出现常见错误的解决方法:基础连接已经关闭: 连接被意外关闭
在我们开发WCF项目的时候,常常会碰到一些莫名其妙的错误,有时候如果根据它的错误提示信息,一般很难定位到具体的问题所在,而由于WCF服务的特殊性,调试起来也不是那么方便,因此往往会花费不少时间来进行跟 ...
- Servlet常见错误及解决方法
常见错误及解决方法 1. 404产生的原因为Web服务器(容器)根据请求地址找不到对应资源,以下情况都会出现404的错误提示: 输入的地址有误(应用名大小写不正确,名称拼写不正确) 在web.xml文 ...
- IIS7常见错误及解决方法
IIS7常见错误及解决方法 问题一:HTTP 错误 500.19 - Internal Server Error 无法访问请求的页面,因为该页的相关配置数据无效. 详细错误信息模块 IIS We ...
- centos linux 系统日常管理4 scp,rsync,md5sum,sha1sum,strace ,find Rsync 常见错误及解决方法 第十七节课
centos linux 系统日常管理4 scp,rsync,md5sum,sha1sum,strace ,find Rsync 常见错误及解决方法 第十七节课 rsync可以增量同步,scp不行 ...
- python循环删除列表元素常见错误与正确方法
python循环删除列表元素 觉得有用的话,欢迎一起讨论相互学习~Follow Me 常见错误 常见错误一:使用固定长度循环删除列表元素 # 使用固定长度循环pop方法删除列表元素 num_list_ ...
- cmd常见错误及解决方法
[英文] Bad command or file name [译文] 错误的命令或文件名 错误原因和解决: 这大概是大家最常见到的错误提示了,它的意思是输入的命令无效.当输入的命令既不是DOS内部命令 ...
- jmeter常见错误及解决方法
jmeter常见错误: 错误一: Response code: Non HTTP response code: java.net.SocketTimeoutException Response m ...
随机推荐
- L2-012 关于堆的判断 (25分) (字符串處理)
将一系列给定数字顺序插入一个初始为空的小顶堆H[].随后判断一系列相关命题是否为真.命题分下列几种: x is the root:x是根结点: x and y are siblings:x和y是兄弟结 ...
- el-table 暂无数据自定义
- excel如何自动获取本周工作日的日期显示作为标题(周一至周五)
一.背景: 每周发周报的标题格式为:本周一到本周五的日期内容,如下:但是每隔一周发送的时候需要改一下周报标题里面的日期,比较麻烦目前的需求是通过函数自动化生成,根据当前的日期去定位出本周一的日期以及本 ...
- Liunx快捷命令(别名)与快捷方式(软/硬链接)
一.快捷命令(别名)-临时生效1.命令:alias 别名='原命令' 2.举例:给检查防火墙的命令设置别名 [root@localhost ~]# alias fhq='firewall-cmd -- ...
- 杂谈 | 在 SEU 开会可以去哪里
空间预约: 健雄书院预约系统 只对吴院人开放,其他人可通过前台志愿者预约. 秉文书院对全校开放(貌似?),需要 提前一天 预约. 借教室需要 提前两天 申请. 图书馆研讨间可以随时约,只是有点难抢. ...
- [转帖]美国出口管制第六番 ECCN编码的藏宝图之旅
https://zhuanlan.zhihu.com/p/585040344 哈喽大家好,这里是大话合规 一旦明确物项受EAR管制(大前提) 下一步就是对物项进行编码 @#¥%&* 这篇文章蜗 ...
- goofys 鲲鹏上面编译挂载与性能测试
goofys 鲲鹏上面编译挂载与性能测试 介质 使用go进行编译. 官网上面有 amd64的介质,但是没有aarch64的介质 需要自行编译 前几天一直编译失败. 周天在家自己测试了一把,根据gith ...
- [转帖]CentOS-7-x86_64-DVD-2009 rpm包列表(centos7.9)
https://www.cnblogs.com/hiyang/p/14803391.html 文件数 4071 个,共3.8G 复制389-ds-base-1.3.10.2-6.el7.x86_64. ...
- [转帖]浅谈RAID写惩罚(Write Penalty)与IOPS计算
https://www.dell.com/community/%E6%95%B0%E6%8D%AE%E5%AD%98%E5%82%A8%E5%92%8C%E4%BF%9D%E6%8A%A4-%E8%B ...
- [转帖]VLAN与三层交换机
目录 一.VLAN概述与优势 二.Trunk的作用 三.IEEE 802.1q 四.VLAN转发 五.Trunk的配置 六.单臂路由概述 七.三层交换机实现VLAN之间通信的原理 八.实验一 九.实验 ...