悬空指针
来源:互联网 发布:网络测试仪的作用 编辑:程序博客网 时间:2024/04/28 08:19
概念
悬空指针:顾名思义,其指向的内存已经被释放,但是指针使用者并不知道,通过指针访问了非法内存,结果随机。悬空指针常发生在指针浅拷贝场景,根本原因是信息不同步问题。
实际场景
最近对引擎做一次比较大升级,结果还是引入了一些隐晦BUG,本文着重还原一个悬空指针的场景。示例代码如下:
class StyleMgr { public:StyleMgr(): _default(NULL), pStyleArr(NULL){ /* .. 其他初始化 ..*/ } //... 析构 ...int Create(const char* file, int index) {Clear();_pStyleArr = new Style[];// ... parse from file...}void Clear() {_hashTb.removeAllObject();delete [] _pStyleArr;_pStyleArr = NULL;}Style* GetStyle(int id) {if (!_default) {_default = _hashTb.find(DEFAULT_CODE);}if (!_hashTb.has_contains(id)) {return _default;}return _hashTb.find(id);}private:Style*_pStyleArr;HashTable _hashTb;Style* _default;};
StyleMgr内部_pStyleArr是样式数组,存储所有style指针,_hashTb为样式哈希表为了快速查找,_default为查找失败的默认样式。_default, _hashTb都与_pStyleArr共享内部指针。
悬空指针出错的场景:
StyleMgr smgr = new StyleMgr();// 1.首次创建...smgr.Create("style.dat", 0);// 2.获取样式...style1 = smgr.GetStyle(id1);style2 = smgr.GetStyle(id2);// 3.其他地方再次创建smgr.Create("style.dat", 1);// 4.悬空指针出场:style3 = smgr.GetStyle(bad_ID);
注意:上面4段代码都不在一个地方。
第二段代码调用GetStyle以后此时_default指向了首次Create时_pStyleArr内部的同时也是_hashTb内部的一个样式。
第三段代码再次调用Create函数,此时Create内部调用Clear以后,重建了_pStyleArr和_hashTb结构,此时_default仍然不为空,持有已经释放的内存地址。
第四段代码再次调用GetStyle时候,如果传入的是合法ID,结果OK!但是当传入非法ID,将_default返回,结果就随机了。。。
原因分析:coding的时候没意识到Create函数会多次重入,Clear函数本意是将整个StyleMgr成员状态重置,忘记处理_default。于是当Create、GetStyle、Create、GetStyle组合调用时,最后一次的GetStyle引入了悬空指针隐患,多次重入取到的默认样式可能随机。
后话
巨大的一个工程中,而且涉及不同地方调用,指望CV很难发现问题。通过gflags也没发现问题,因为只有查找失败时才返回default样式,而且返回后还不一定出错。
这个BUG是代码提交十天后才发现,当时跟踪另外一个bug,调试的时候偶然发现_default指向内容为空。。。然后就查啊查啊查。。。
查到问题改起来十分容易啦~
指针问题没有小问题,对待指针问题一定小心又小心。。。
http://blog.csdn.net/ryfdizuo/article/details/22859499
- 悬空指针
- 悬空指针
- 又见悬空指针
- malloc & 悬空指针
- 悬空指针与野指针
- 野指针和悬空指针
- 动态分配内存与悬空指针
- c语言中指针悬空
- 什么是野指针?迷途指针!悬空指针!
- 野(wild)指针与悬空(dangling)指针
- C++随笔——悬空指针
- 【LVL1_7_c】【思考题】【1】什么是野指针 悬空指针
- 内存出错,内存泄露,数组越界,悬空指针,错误分配
- 【每日一C之二十】 悬空指针
- 从unique_ptr赋值到shared_ptr引起的指针悬空bug
- C++随笔——悬空指针(dangling pointers)
- 程序猿之---C语言细节22(函数返回指针注意事项<悬空指针>、查看进程可以分配的内存大小)
- POJ 1003 Hangover 悬空
- hbase api
- Spring4.0MVC学习资料,简单学习教程(一)
- 10道iOS面试题(高级)
- bootstrap之Swipe
- usaco2.4.3穿越栅栏(最短路)
- 悬空指针
- 指向函数的指针
- NYOJ 40 公约数和公倍数
- 导出数据库任意表数据为EXCEL
- Bootstrap_V1.9移植
- C++ 中include头文件时尖括号<>与双引号""的区别
- Quartz2D一点点
- 开始过码农的日子--我将用我点点的时间记下每天点点的成长
- OSGI学习系列(一)搭建OSGI环境(Equinox)