免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
楼主: Godbach
打印 上一主题 下一主题

如何有效的避免指针在释放之后被引用? [复制链接]

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
41 [报告]
发表于 2008-11-08 15:42 |只看该作者
这样说也有自身合理的地方。但是在内核中,有时出现这样的情况,那不但是程序crash,而是kernel panic,甚至OOPS都没有,直接重启了。

最近刚完成一个项目。项目是在老外原有的代码上增加新的功能。以前写代码时习惯了在用指针前先检查一下指针是否为空。所以在这个项目也是这样做的。
但老外直接跟我们说不要那样干,那样会隐藏你的BUG。
想想也是有道理的。从逻辑上来讲,有时候根本不允许所用的指针为空,如果用判断来知道这个指针是空的,这时又要怎么办呢?输出一句话让调试的人
知道有错误了? 他们的做法是只在新申请的内存时检查是否为空,如果为空就做些内存清理的工作,腾出些空间。在其他用指针的环境下都不检查
指针是否为空。该调用方法的就调用方法,该往内存中写的就写。如果指针是空就让程序 crash 掉。这些能及时发现问题。如果不能及时发现问题,那只
能证明所做的测试还不够。

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
42 [报告]
发表于 2008-11-08 15:46 |只看该作者
原帖由 samon_fu 于 2008-11-7 17:48 发表
要想成为一个好的程序员(?兄弟们别老想着程序员啊),习惯很重要。
而一个好习惯的养成始于态度。

兄弟们每写一行代码的时候,想着这代码以后要给自己看,就OK了:),

很多时候思路比写、调试代码重要 ...


确实,要有一个认真的心态。应该保证自己什么时候看,都可以看懂,不需要再想半天。那样别人看起来,可能就要想一个星期甚至更长时间。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
43 [报告]
发表于 2008-11-08 17:06 |只看该作者
原帖由 Godbach 于 2008-11-8 15:39 发表

如果我处理的是网络数据包,当内核遇上这样的NULL时,连OOPS都没有。内核告诉我,偶要重启了,呵呵

内核不会这么差劲吧?
况且,重启也不是什么坏事情吧。

论坛徽章:
36
IT运维版块每日发帖之星
日期:2016-04-10 06:20:00IT运维版块每日发帖之星
日期:2016-04-16 06:20:0015-16赛季CBA联赛之广东
日期:2016-04-16 19:59:32IT运维版块每日发帖之星
日期:2016-04-18 06:20:00IT运维版块每日发帖之星
日期:2016-04-19 06:20:00每日论坛发贴之星
日期:2016-04-19 06:20:00IT运维版块每日发帖之星
日期:2016-04-25 06:20:00IT运维版块每日发帖之星
日期:2016-05-06 06:20:00IT运维版块每日发帖之星
日期:2016-05-08 06:20:00IT运维版块每日发帖之星
日期:2016-05-13 06:20:00IT运维版块每日发帖之星
日期:2016-05-28 06:20:00每日论坛发贴之星
日期:2016-05-28 06:20:00
44 [报告]
发表于 2008-11-09 11:05 |只看该作者
原帖由 flw 于 2008-11-8 17:06 发表

内核不会这么差劲吧?
况且,重启也不是什么坏事情吧。


呵呵,可能这是因为我的内核模块的问题。因为在处理网络数据包的过程,当数据包超过某个pps时,系统直接就重启了。调试了很久,发现是因为当数据包量大时,网卡可能会丢包,程序里面kfree了。但是我后面又引用了skb。因为正常情况下,是可以引用的。后来解决问题的方法就是把这两行代码对调一下位置。

论坛徽章:
0
45 [报告]
发表于 2008-11-09 11:44 |只看该作者
// Template of smart pointer
// The class T must have Lock() & Unlock() methods
template<class T> class SmartPtr {
public:
        explicit SmartPtr(T *t = 0) : pt(t) { Inc(); }
        SmartPtr(const SmartPtr<T> & p) : pt(p.pt) { Inc(); }
        ~SmartPtr() { Dec(); }
        operator bool() const { return pt != 0; }
        T *operator->() const { return pt; }

        bool operator==(const SmartPtr<T> & p) const { return pt == p.pt; }
        bool operator!=(const SmartPtr<T> & p) const { return pt != p.pt; }

        SmartPtr<T> &operator=(const SmartPtr<T> & p) {
                if (pt != p.pt)
                        Dec(), pt = p.pt, Inc();
                return *this;
        }

private:
        void Inc() const { if (pt) pt->Lock(); }
        void Dec() const { if (pt) pt->Unlock(); }
        T &operator*();
        T *pt;
};



以上代码是GNUGK中的一个使用引用计数的模板。

论坛徽章:
0
46 [报告]
发表于 2008-11-09 11:49 |只看该作者
原帖由 flyeleph 于 2008-11-7 23:32 发表
最近刚完成一个项目。项目是在老外原有的代码上增加新的功能。以前写代码时习惯了在用指针前先检查一下指针是否为空。所以在这个项目也是这样做的。
但老外直接跟我们说不要那样干,那样会隐藏你的BUG。
想想 ...



你说的和我代码风格有些类似,不过我不是直接使用指针,而是如果指针为空直接exit,并输入信息。
如果直接使用指针,有时候未必能找到问题。因为有可能指针指向的内存被重新申请了,或者你从内存池获得的内存。到最后,出错的结果往往是莫名其妙的。

论坛徽章:
0
47 [报告]
发表于 2008-11-09 11:58 |只看该作者
原帖由 flw 于 2008-11-7 13:45 发表
从某种程度上讲,那种所谓的 1 == a 和 free(p); p=NULL; 还有 memset(buf,0x00,sizeof(buf)); strcpy(buf,str); 等预防 BUG 的技巧恰恰是在阻碍程序员的成长。

写程序一定要注意语义,语义清晰,错误就会少 ...


memset(buf,0x00,sizeof(buf)); strcpy(buf,str);


汗~我就经常这样些,要不每次只能
strcpy(buf, str);
buf[strlen[str]] = '\0';


我当年就专门就字符串拷贝自动加\0的问题,专门看了strcpy 和 strncpy的源代码。发现都不是我想要的。虽说strncpy能自动加\0,但也有例外。就是当str的长度等与n的时候,不会加\0

字符串拷贝就改成
strncpy(buf, str, sizeof(buf) - 1);
buf[sizeof(buf) - 1] = '\0';

至于sprint 和snprint的代码看了头晕,就懒得去研究

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
48 [报告]
发表于 2008-11-09 16:38 |只看该作者
原帖由 smzgl 于 2008-11-9 11:58 发表
要不每次只能
strcpy(buf, str);
buf[strlen[str]] = '\0';

看来我说的还真是一点儿也没错。
确实是阻止了你的成长。

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
49 [报告]
发表于 2008-11-09 16:40 |只看该作者
> 至于 .... snprint 的代码看了头晕,就懒得去研究
最好用的函数居然懒得去研究……
而且我要再一次批评一下通过研究库函数的实现来研究库函数的功能这种做法。

论坛徽章:
0
50 [报告]
发表于 2008-11-09 18:26 |只看该作者

回复 #49 flw 的帖子

不是有man手册吗? 想了解库函数的功能足够了啊。

另:在内核里,空指针确实是非常恐怖的一件事情,一般就是panic、crash, then reboot,呵呵。
经验丰富一点的,还是可以通过看寄存器里的东东来调试哦。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP