死循环的原因大概找到了,是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; }
|
之前基本上是学习原有代码,这个算是又一点不同的收获吧。
没有评论:
发表评论