我对VS2010上的代码有一个非常烦人的问题:
template <class N>
size_t NumericIndex<N>::GetPageIndex(const PageRef& page, Id id) const
{
size_t size=page->entries.size();
if (size>0) {
size_t left=0;
size_t right=size-1;
size_t mid;
while (left<=right) {
mid=(left+right)/2;
if (page->entries[mid].startId<=id &&
(mid+1>=size || page->entries[mid+1].startId>id)) {
return mid;
}
else if (page->entries[mid].startId<id) {
left=mid+1;
}
else {
right=mid-1;
}
}
}
return size;
}
它通过以下方法调用:
template <class N>
bool NumericIndex<N>::GetOffset(const N& id,
FileOffset& offset) const
{
size_t r=GetPageIndex(root,id);
...
}
问题在于,在方法的第一次调用中一切正常,size
,left
和right
已初始化,但在第二次调用时,它会直接跳转到行while (left<=right) {
,跳过此行之前的每个操作,并使用垃圾初始化right
。
你知道问题出在哪里吗?
提前致谢。
代码是项目libosmscout的一部分。
[编辑]
Arne Mertz解决了这个问题。实际上这是循环的第二遍。由于size_t是无符号类型,因此当mid == 0且right = mid-1时,我们会出现溢出。
修复代码应为:
template <class N>
size_t NumericIndex<N>::GetPageIndex(const PageRef& page, Id id) const
{
size_t size=page->entries.size();
if (size>0) {
size_t left=0;
size_t right=size-1;
size_t mid;
while (left<=right) {
mid=(left+right)/2;
if (page->entries[mid].startId<=id &&
(mid+1>=size || page->entries[mid+1].startId>id)) {
return mid;
}
else if (page->entries[mid].startId<id) {
left=mid+1;
}
else {
if (mid == 0) {
return size;
}
right=mid-1;
}
}
}
return size;
}