金庆的专栏

  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  423 随笔 :: 0 文章 :: 454 评论 :: 0 Trackbacks
前几天,KOK3客户端因为我的资源配置错误而崩溃了。
调试器带我到了出错的代码行,是一个空指针解引用。
代码大致如下:

    Item* pItem = itemList.getItem(index);
    return *pItem;

getItem方法如下:

Item* ItemList::getItem(int index)
{
    if (index < 0) return NULL;
    if (index >= size()) return NULL;
    return _list[index];
}

错误是因为资源加载出错,列表为空,所以getItem()返回NULL.

对于资源加载出错,应该加载时就提示出错,不应该在使用时才报错。

getItem()做了索引越界出错处理,所以它的调用者必须检查其返回值。

假设ItemList的指针元素保证不为空,正常情况下,索引正确情况下都不会返回空指针。
这种情况下,添加断言是必要的。

    Item* pItem = itemList.getItem(index);
    assert(pItem);
    return *pItem;

Item* ItemList::getItem(int index)
{
    ...
    assert(_list[index]);
    return _list[index];
}
    

对与索引值,还是用无符号数为好,可省去下界溢出断。

posted on 2010-02-11 09:48 金庆 阅读(4444) 评论(11)  编辑 收藏 引用 所属分类: 1. C/C++2. 网游开发

评论

# re: 需要判断指针为空吗[未登录] 2010-02-11 10:19 Bill Hsu
楼主是巨人的?  回复  更多评论
  

# re: 需要判断指针为空吗[未登录] 2010-02-11 10:49 kevin lynx
这个问题在我们组里也备受争议。有人觉得对每个指针进行拿捏然后再决定判断,很多余,所以索性对所有指针进行空判断;有人觉得没必要写那么多冗余代码,需要对每个指针进行上下文审查。

拿一个接口为例,接口实现里是否有必要对参数进行判断?接口调用者是否需要对返回值做判断?反正这种事情挺纠结的.  回复  更多评论
  

# re: 需要判断指针为空吗 2010-02-11 11:19 Jimixu
简简单单的从两个if不写在一起,用||隔开就看出LZ功力非凡,可以节省很多不必要的判断
Item* ItemList::getItem(int index)
{
if (index < 0) return NULL;
if (index >= size()) return NULL;
return _list[index];
}
  回复  更多评论
  

# re: 需要判断指针为空吗[未登录] 2010-02-11 11:50 zz
@Jimixu
两个if写在一起用||隔开会增加很多判断吗?不解。
如果第一个条件成立,||的后一个条件不是不会判断了吗?  回复  更多评论
  

# re: 需要判断指针为空吗 2010-02-11 11:58 jQuery
@Jimixu

=_=
  回复  更多评论
  

# re: 需要判断指针为空吗[未登录] 2010-02-11 12:37 绝对零度
@Jimixu
有这种讲解吗?  回复  更多评论
  

# re: 需要判断指针为空吗 2010-02-11 16:18 金庆
@kevin lynx
我的观点是:只要有可能为空的,就一定要判断是否为空; 不可能为空的,可以用一个assert断言来表达。
关键在于判断是否有可能为空。由函数调用者保证不为空的,就认为不可能为空,可在函数说明中注释并在函数开始处加个断言。由进程以外输入决定的,如用户输入,文件输入,或其他进程传入数据决定的指针,即使外部接口规定了不会造成空指针,但仍应该对输入判断。外部输入错误不应该造成程序错误。  回复  更多评论
  

# re: 需要判断指针为空吗 2010-02-13 17:01 陈梓瀚(vczh)
理论上,对于一个对象A,如果他不能在这个上下文里面取到所有类型T的值,那么A的类型就不能是T。

举个例子,句柄可以是个指针。但是如果有规定是不能为空,那就去搞个句柄类。无论你在哪里使用,都可以在复制和构造的时候集中检查。譬如,句柄的构造函数可以检查传入的指针,为空就崩溃。只要构造成功了,那么句柄里面的内部指针肯定不会是空的。  回复  更多评论
  

# re: 需要判断指针为空吗[未登录] 2010-02-15 16:24 Steven
我是比较推崇这样的写法的
if (index < 0) return NULL;
if (index >= size()) return NULL;
虽然用 || 可以生成一样的汇编代码,但是对于调试维护来说是有区别的
如果我用 || 的话,并且在return 之前,输出一些错误log
if (index < 0 || index >= size())
{
cout << "invalide index";
return null;
}
当我看到这个log的时候,你怎么才能知道到底是哪个判断出错了呢?index是太大还是太小呢?当然你可以说我应该把index的值也一并输出出来,但是在实践中很多判断是很复杂的,很难输出所有的值,比如长字符串的比较,总不能输出那么多东西到log里吧。  回复  更多评论
  

# re: 需要判断指针为空吗 2010-05-12 22:00 classyk
索引值用无符号数并不能减少判断,反而更加麻烦  回复  更多评论
  

# re: 需要判断指针为空吗 2010-05-13 09:38 金庆
@classyk
传统的C程序中是int类型到处使用,而在C++中更倾向于各种功能用不同的类型,如容器大小用size_t. 用无符号数减少了小于0的判断,“更加麻烦”在哪里?  回复  更多评论
  


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理