2009年1月31日星期六

std::find学习

死循环的原因大概找到了,是std::find使用不当的问题。
SGI的说明中函数原型为:
templateInputIterator, class EqualityComparable>
InputIterator find(InputIterator first, InputIterator last,
const EqualityComparable& value);
函数返回值为[first, last)范围内,第一个值等于value的迭代器。如果不存在,则返回last。前提是first与
last之间是一个有效地范围。没有提到first位于last之后的情况。但就实际情况来说,如果出现这种情况,仍
然返回last。环境为Linux,libstdc++.so.6。
原先的代码

1 inline T * Find(const T& v) {
2 T * p = std::find(objs, objs + count, v);
3 while (p && p->Full())
4 {
5 p = std::find(p + 1, objs + count, v);
6 }
7 return (p == objs + count) ? 0 : p;
8 }

问题在于,如果查找的对象不存在,第2行返回值为objs+count。而进入循环进行,条件检测均可以满足。接下来第5行,由于p + 1已经位于objs + count之后,所以返回值依然为objs + count。从而陷入了死循环。
可能是原作者也存在和我同样的误解,武断的认为如果不存在满足查找条件的对象,std::find会返回空指针。
修改后的代码如下,也就是多加了一项对于p是否为objs+count的判断。

inline T * Find(const T& v) {
T * p = std::find(objs, objs + count, v);
while (p && (p != objs + count) && p->Full())
{
p = std::find(p + 1, objs + count, v);
}
return (p == objs + count) ? 0 : p;
}

之前基本上是学习原有代码,这个算是又一点不同的收获吧。

没有评论: