mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-22 20:41:20 +00:00
[util] Fix an out-by-one in QF_bsearch_r
And rename _bsearch to QF_bsearch_r since that's far less confusing. Also, update the test to make it possible for valgrind to detect the out-by-one. The problem was found when trying to remove components from an entity when using subpools.
This commit is contained in:
parent
370c36f6cc
commit
76ac446156
4 changed files with 19 additions and 13 deletions
|
@ -35,7 +35,7 @@
|
|||
typedef int (*__compar_d_fn_t)(const void *, const void *, void *);
|
||||
#endif
|
||||
|
||||
void *_bsearch(const void *key, const void *base, size_t nmemb, size_t size,
|
||||
__compar_d_fn_t cmp, void *arg);
|
||||
void *QF_bsearch_r(const void *key, const void *base, size_t nmemb, size_t size,
|
||||
__compar_d_fn_t cmp, void *arg);
|
||||
|
||||
#endif// quicksort_h
|
||||
|
|
|
@ -109,7 +109,7 @@ size_t strndup (const char *str, size_t len);
|
|||
|
||||
#ifndef HAVE_BSEARCH_R
|
||||
# include "bsearch.h"
|
||||
# define bsearch_r _bsearch
|
||||
# define bsearch_r QF_bsearch_r
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_QSORT_R
|
||||
|
|
|
@ -63,13 +63,12 @@ void *fbsearch_r (const void *key, const void *_base, size_t nmemb, size_t size,
|
|||
}
|
||||
|
||||
void *
|
||||
_bsearch(const void *key, const void *_base, size_t nmemb, size_t size,
|
||||
__compar_d_fn_t cmp, void *arg)
|
||||
QF_bsearch_r(const void *key, const void *_base, size_t nmemb, size_t size,
|
||||
__compar_d_fn_t cmp, void *arg)
|
||||
{
|
||||
// fuzzy bsearh
|
||||
const char *base = (const char *) _base;
|
||||
unsigned left = 0;
|
||||
unsigned right = nmemb;
|
||||
unsigned right = nmemb - 1;
|
||||
unsigned mid;
|
||||
const void *p = 0;
|
||||
int c;
|
||||
|
|
|
@ -29,16 +29,19 @@
|
|||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "QF/fbsearch.h"
|
||||
#include "bsearch.h"
|
||||
|
||||
// will be prefix-summed
|
||||
int data[] = {
|
||||
int srcdata[] = {
|
||||
2, 1, 3, 1, 2, 2, 5, 4,
|
||||
2, 1, 3, 1, 2, 2, 5, 4,
|
||||
};
|
||||
#define nele ((int) (sizeof (data) / sizeof (data[0])))
|
||||
#define nele ((int) (sizeof (srcdata) / sizeof (srcdata[0])))
|
||||
int *data;
|
||||
|
||||
static int
|
||||
compare (const void *a, const void *b)
|
||||
|
@ -83,6 +86,9 @@ main(int argc, const char **argv)
|
|||
int ret = 0;
|
||||
int *p;
|
||||
|
||||
data = malloc (nele * sizeof (int));
|
||||
memcpy (data, srcdata, nele * sizeof (int));
|
||||
|
||||
for (int i = 1; i < nele; i++) {
|
||||
data[i] += data[i - 1];
|
||||
}
|
||||
|
@ -99,18 +105,19 @@ main(int argc, const char **argv)
|
|||
ret |= 1;
|
||||
}
|
||||
if (p && i == *p) {
|
||||
p = _bsearch (&i, data, nele, sizeof (int), compared, 0);
|
||||
p = QF_bsearch_r (&i, data, nele, sizeof (int), compared, 0);
|
||||
if (!p || *p != i) {
|
||||
printf ("_bsearch did not find %d, but should have\n", i);
|
||||
printf ("QF_bsearch_r did not find %d, but should have\n", i);
|
||||
ret |= 1;
|
||||
}
|
||||
} else {
|
||||
p = _bsearch (&i, data, nele, sizeof (int), compared, 0);
|
||||
p = QF_bsearch_r (&i, data, nele, sizeof (int), compared, 0);
|
||||
if (p) {
|
||||
printf ("_bsearch found %d, but should not have\n", i);
|
||||
printf ("QF_bsearch_r found %d, but should not have\n", i);
|
||||
ret |= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
free (data);
|
||||
return ret;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue