关于memset,malloc以及free后的野指针误区详解
1.首先来看看memset这个函数 void *memset(void *s, int c, size_t n);
memset函数的功能是将一段内存初始化为某个特定的值,并且初始化内存是以内存为单位的。
memset一般用来将内存初始化为0,如果我们将一段内存初始化为1或者其他值得话就要慎用了。
我们看个最直接的 memset例子就很清楚了。
#include<stdio.h>
#include<stdlib.h>
#include<string.h>int main(void)
{unsigned int a[2];memset(a,1,2*sizeof(int));printf("a:%d\n",a[0]);
}
最后运行的结果为16843009,只是因为memset在初始化的时候是以字节为单位进行初始化的,由于在32的系统中int是四个字节,因此a[0]的值初始化为0x01010101=16843009。
如果将数组类型改为char型的初始化为1则不会出现问题。
2.malloc函数原型为void *malloc(size_t size),一般用来给指针申请内存的,申请的内存存在堆里面,这个申请的内存必须手动释放系统不会自主释放。
我们在使用malloc申请内存时,可能申请的内存已经使用过,因此我们在申请完有效内存后我们要习惯性的将内存清0,避免不必要的错误。
int *ptr;
ptr = (int *)malloc(1024*sizeof(int));
memset(ptr,0,1024*sizeof(int));
3.最后我们来看看free函数的误区
free函数原型为:void free(void *ptr);
free 和delete函数在使用时,它们只是把指针所指的内存给释放掉,但并没有把指针本身干掉。
用调试器跟踪示例程序,发现指针p 被free 以后其地址仍然不变(非NULL),只是该地址对应的内存是垃圾,p 成了“野指针”。如果此时不把p 设置为NULL,会让人误以为p 是个合法的指针。
如果程序比较长,我们有时记不住p 所指的内存是否已经被释放,在继续使用p 之前,通常会用语句if (p != NULL)进行防错处理。很遗憾,此时if 语句起不到防错作用,因为即便p 不是NULL 指针,它也不指向合法的内存块。
char *p = (char *) malloc(100);
strcpy(p, “hello”);
free( p ); // p 所指的内存被释放,但是p 所指的地址仍然不变
…
if(p != NULL) // 没有起到防错作用
{
strcpy(p, “world”); // 出错
}
函数体内的局部变量在函数结束时自动消亡。很多人误以为上面示例是正确的。理由是p 是局部的指针变量,它消亡的时候会让它所指的动态内存一起完蛋。这是错觉!
void Func(void)
{
char *p = (char *) malloc(100); // 动态内存会自动释放吗?
}
上述例子,试图让动态内存自动释放
我们发现指针有一些“似是而非”的特征:
(1)指针消亡了,并不表示它所指的内存会被自动释放。
(2)内存被释放了,并不表示指针会消亡或者成了NULL 指针。
如何杜绝野指针?
“野指针”不是NULL 指针,是指向“垃圾”内存的指针。人们一般不会错用NULL指针,因为用if 语句很容易判断。但是“野指针”是很危险的,if 语句对它不起作用。
“野指针”的成因主要有两种:
(1)指针变量没有被初始化。任何指针变量刚被创建时不会自动成为NULL 指针,它的缺省值是随机的,它会乱指一气。所以,指针变量在创建的同时应当被初始化,要么将指针设置为NULL,要么让它指向合法的内存。例如
char *p = NULL;
char *str = (char *) malloc(100);
(2)指针p 被free 或者delete 之后,没有置为NULL,让人误以为p 是个合法的指针。
关于memset,malloc以及free后的野指针误区详解相关推荐
- 高位在前低位在后是啥意思_详解MACD指标的死叉卖点:低位死叉+高位死叉+零轴附近死叉...
MACD最经典最简单的的用法就是金叉死叉了,但是对于这样简单的用法,想必还是有很多的股民不知道如何运用,所以今天越声攻略就给大家详细的讲解下详解MACD指标的死叉卖点:低位死叉+高位死叉+零轴附近死叉 ...
- 【机器学习】【隐马尔可夫模型-3】后向算法:算法详解+示例讲解+Python实现
0.前排提示 csdn有些数学公式编辑不出来,所以本博用容易书写的表达式来表示专业数学公式,如: (1) 在本博客中用α<T>(i)来表示 (2)在本博客中用[i=1, N]∑来表示 注 ...
- 酷6网证实80后员工猝死 内部邮件详解死因
本文转载自 MSN ,原文地址: http://msn.ynet.com/view.jsp?oid=58168767 相关阅读: 多少钱也不能买我的命 --Leo 谈酷 6 程序员猝死 日前,有关酷 ...
- 前序遍历、中序遍历、后序遍历层序遍历详解附代码(数据结构C语言)
目录 (1)前序遍历 (DLR) 递归算法 (2)中序遍历 (LDR) 递归算法 (3)后序遍历 (LRD) 递归算法 (4)层序遍历 队列实现方法 层序遍历的定义: 实现方法: 代码实现 结果截图 ...
- ceres实现的pnp解算后的位姿优化代码详解
论文阅读模块将分享点云处理,SLAM,三维视觉,高精地图相关的文章.公众号致力于理解三维视觉领域相关内容的干货分享,欢迎各位加入我,我们一起每天一篇文章阅读,开启分享之旅,有兴趣的可联系微信diany ...
- truncate数据后回收空间_Truncate用法详解
前言: 当我们想要清空某张表时,往往会使用truncate语句.大多时候我们只关心能否满足需求,而不去想这类语句的使用场景及注意事项.本篇文章主要介绍truncate语句的使用方法及注意事项. 1.t ...
- 笔记本电脑电池怎么拆_笔记本电脑进水后遗症有哪些 笔记本进水后正确处理方法【详解】...
有些笔记本电脑进水 后,由于后续处理不及时或者处理不恰当,就会出现一些后遗症,在这种情况下,你的笔记本只能送去维修了,很多人都想知道,笔记本电脑进水有哪些后遗症呢?怎么处理才是正确的呢?今天小编就带大 ...
- 利用OpenCV的霍夫变换线检测函数HoughLines()得到直线的ρ和θ值后绘制直线的原理详解
为了更好地看懂本文,大家可以先看下我写的另一篇博文,链接如下: https://blog.csdn.net/wenhao_ir/article/details/51774444 OpenCV的霍夫变换 ...
- SAP CRM Fiori My appointment点了Edit按钮后的三个roundtrip详解
my appointment edit之后有3个sequential 的roundtrip 我看了下现在的三组串行的roundtrip,我觉得我们需要搞清楚第三组到底会不会阻塞user的ui操作: a ...
最新文章
- shell脚本求和_【零基础学云计算】Shell编程之case语句与循环语句
- input标签加disabled属性后无法获得其value值
- 五、开始学习Excel函数,效率快速提高
- java反射的工具类的函数集合
- Dart的套接字与web套接字
- 如何用 Python 从 0 开始创建一个区块链?
- ElectronNetTest
- redis运维问题集锦FAQ
- Python字符串逆序输出六种方法
- 利用不共线三点求解并联机构动系在定系中的位姿
- DllMain 参数解释
- w10计算机右键管理,Win10右键菜单怎么管理
- 安卓手机更新过程手机乱码_关于安卓手机上自带播放器乱码问题的解决
- display:flex flex-grow
- Eclipse护眼背景及字体设置
- 微信小程序嵌套iframe_H5嵌入微信小程序踩过的坑
- 基于平移布林通道的系统
- 【昭阳】开源第1弹 mybatis-genl
- 海信研发前端工程师面试经验总结
- 图像处理中的距离含义
热门文章
- vue后台管理知识点、难点总结01
- Dojo Charting 控件高级用法
- 江西专升本考试作弊事件,为什么最近考试作弊事件频发?
- uni-app实现联系人右侧索引字母表点击滚动到相应的位置(uni.pageScrollTo(OBJECT))
- 计算机学院职业规划大赛策划书,大学生职业生涯规划大赛策划书(策划书范文).doc...
- 收集得最全的sql 语句
- SQL语句的强大综合集锦
- 如何选择一台好的拨号服务器?
- video.js插件播放hls、rtmp
- allowMultiQueries 设置为true不生效问题