一个二分查找的core,求教......实在搞不定了

wklken 2012-08-23 06:24:07
数据是这样的
id1 score1 id2 score2
id是升序的
传入一个值queryid,用二分查找去匹配id

代码如下

int mid = ((start + end) / 2) & 0xfffffffe;
if (pdata[mid] == queryid){
if (mid+1 < fv.m_num){
finalScore = *(pdata + mid + 1);
}
break;
}
else if (pdata[mid] < queryid){
start = mid + 2;
}
else {
end = mid - 2;
}

然后,就莫名其妙core掉了,晕死,单元测试,造各种异常值,都没办法复现
需要复现原因
求救....
...全文
201 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
wklken 2012-08-24
  • 打赏
  • 举报
回复
多谢两位,我后续再去查找些资料吧
有点感觉是p[mid]超出了寻址范围,core掉了
单机测不出core
赵4老师 2012-08-24
  • 打赏
  • 举报
回复

http://www.microsoft.com/visualstudio/en-us/products/2010-editions/visual-cpp-express
右边Visual C++ 2010 Express下面的Select language...下拉选‘简体中文’,再按Install Now按钮

再参考
C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\bsearch.c
/***
*bsearch.c - do a binary search
*
* Copyright (c) Microsoft Corporation. All rights reserved.
*
*Purpose:
* defines bsearch() - do a binary search an an array
*
*******************************************************************************/

#include <cruntime.h>
#include <stdlib.h>
#include <search.h>
#include <internal.h>

#if defined (_M_CEE)
#define __fileDECL __clrcall
#else /* defined (_M_CEE) */
#define __fileDECL __cdecl
#endif /* defined (_M_CEE) */
/***
*char *bsearch() - do a binary search on an array
*
*Purpose:
* Does a binary search of a sorted array for a key.
*
*Entry:
* const char *key - key to search for
* const char *base - base of sorted array to search
* unsigned int num - number of elements in array
* unsigned int width - number of bytes per element
* int (*compare)() - pointer to function that compares two array
* elements, returning neg when #1 < #2, pos when #1 > #2, and
* 0 when they are equal. Function is passed pointers to two
* array elements.
*
*Exit:
* if key is found:
* returns pointer to occurrence of key in array
* if key is not found:
* returns NULL
*
*Exceptions:
* Input parameters are validated. Refer to the validation section of the function.
*
*******************************************************************************/

#ifdef __USE_CONTEXT
#define __COMPARE(context, p1, p2) (*compare)(context, p1, p2)
#else /* __USE_CONTEXT */
#define __COMPARE(context, p1, p2) (*compare)(p1, p2)
#endif /* __USE_CONTEXT */

#if !defined (_M_CEE)
_CRTIMP
#endif /* !defined (_M_CEE) */

SECURITYSAFECRITICAL_ATTRIBUTE
#ifdef __USE_CONTEXT
void * __fileDECL bsearch_s (
REG4 const void *key,
const void *base,
size_t num,
size_t width,
int (__fileDECL *compare)(void *, const void *, const void *),
void *context
)
#else /* __USE_CONTEXT */
void * __fileDECL bsearch (
REG4 const void *key,
const void *base,
size_t num,
size_t width,
int (__fileDECL *compare)(const void *, const void *)
)
#endif /* __USE_CONTEXT */
{
REG1 char *lo = (char *)base;
REG2 char *hi = (char *)base + (num - 1) * width;
REG3 char *mid;
size_t half;
int result;

/* validation section */
_VALIDATE_RETURN(base != NULL || num == 0, EINVAL, NULL);
_VALIDATE_RETURN(width > 0, EINVAL, NULL);
_VALIDATE_RETURN(compare != NULL, EINVAL, NULL);

/*
We allow a NULL key here because it breaks some older code and because we do not dereference
this ourselves so we can't be sure that it's a problem for the comparison function
*/

while (lo <= hi)
{
if ((half = num / 2) != 0)
{
mid = lo + (num & 1 ? half : (half - 1)) * width;
if (!(result = __COMPARE(context, key, mid)))
return(mid);
else if (result < 0)
{
hi = mid - width;
num = num & 1 ? half : half-1;
}
else
{
lo = mid + width;
num = half;
}
}
else if (num)
return (__COMPARE(context, key, lo) ? NULL : lo);
else
break;
}

return NULL;
}

#undef __fileDECL
#undef __COMPARE
pengzhixi 2012-08-24
  • 打赏
  • 举报
回复
既然是越界 那就加些判断呗
wklken 2012-08-24
  • 打赏
  • 举报
回复
定位到原因,越界了,但是貌似c++对越界不管的,p[mid]指针指向位置取值

所以,搜索不到就返回了

但是一到线上,流量一进来就core掉了,应该是发生了什么

是不是p[mid]存在一种情况,超出了内存寻址范围,然后core了,一般情况下如果越界读值,不会core的吧?
pengzhixi 2012-08-24
  • 打赏
  • 举报
回复
你都不判断下mid是否越界的吗?pdata + mid + 1
start = mid + 2;
end = mid - 2;
这些都可能越界
图灵狗 2012-08-24
  • 打赏
  • 举报
回复
这跟内存分配和寻址方式没什么联系,你用的是数组,地址是连续分配的,只要保证不越界就好了。

[Quote=引用 9 楼 的回复:]

定位到问题了,
修改问题:

p[mid]

mid一直往上加,什么时候会core掉?
不熟悉c++内存分配和寻址方式,求教

哪位回答下哈,谢谢
准备结帖了
[/Quote]
wklken 2012-08-24
  • 打赏
  • 举报
回复
定位到问题了,
修改问题:

p[mid]

mid一直往上加,什么时候会core掉?
不熟悉c++内存分配和寻址方式,求教

哪位回答下哈,谢谢
准备结帖了

wklken 2012-08-23
  • 打赏
  • 举报
回复
用真实数据运行,也没有发现问题
因为使用的是int32,如果构造数超出32位,单独构造没发现什么问题,但是若是大批量访问,会不会存在问题?
GankerZZl 2012-08-23
  • 打赏
  • 举报
回复
看不出来...坐等高人
wklken 2012-08-23
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 的回复:]

引用 4 楼 的回复:

引用 3 楼 的回复:

那能确保一定会命中吗?


不确保,
数据格式

10001 10 10002 20
多字段少字段都试过了,也不会core.....


那不能命中的时候你是怎么让递归或者循环结束的呢?
[/Quote]

不要意思,刚才太急,复制少了

while(start <= end){
int mid = ((start + end) / 2) & 0xfffffffe;
if (pdata[mid] == queryid){
if (mid+1 < fv.m_num){
finalScore = *(pdata + mid + 1);
}
break;
}
else if (pdata[mid] < queryid){
start = mid + 2;
}
else {
end = mid - 2;
}
}



GankerZZl 2012-08-23
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 的回复:]

引用 3 楼 的回复:

那能确保一定会命中吗?


不确保,
数据格式

10001 10 10002 20
多字段少字段都试过了,也不会core.....
[/Quote]

那不能命中的时候你是怎么让递归或者循环结束的呢?
wklken 2012-08-23
  • 打赏
  • 举报
回复
[Quote=引用 3 楼 的回复:]

那能确保一定会命中吗?
[/Quote]

不确保,
数据格式

10001 10 10002 20
多字段少字段都试过了,也不会core.....
GankerZZl 2012-08-23
  • 打赏
  • 举报
回复
那能确保一定会命中吗?
wklken 2012-08-23
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]

2分不是一个递归查找吗,你递归结束的条件是什么? mid为什么是加2或减2,而不是1呢?
[/Quote]

序列是成对出现的
id score为一对,对id使用二分,所以每次存在+-2的操作

结束条件是命中
pdata[mid] == queryid
GankerZZl 2012-08-23
  • 打赏
  • 举报
回复
2分不是一个递归查找吗,你递归结束的条件是什么? mid为什么是加2或减2,而不是1呢?

64,648

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧