I am making a function to get the maximum value of an array of NMEMB members each one of size SIZ,
comparing each member with memcmp()
. The problem is that when comparing signed integers the result is incorrect but at the same time correct. Here is an example:
void *
getmax(const void *data, size_t nmemb, size_t siz){
const uint8_t *bytes = (const uint8_t *)data;
void *max = malloc(siz);
if (!max){
errno = ENOMEM;
return NULL;
}
memcpy(max, bytes, siz);
while (nmemb > 0){
hexdump(bytes, siz);
if (memcmp(max, bytes, siz) < 0)
memcpy(max, bytes, siz);
bytes += siz;
--nmemb;
}
return max;
}
int
main(int argc, char **argv){
int v[] = {5, 1, 3, 1, 34, 198, -12, -11, -0x111118};
size_t nmemb = sizeof(v)/sizeof(v[0]);
int *maximum = getmax(v, nmemb, sizeof(v[0]));
printf("%d\n", *maximum);
return 0;
}
hexdump()
is just a debugging function, doesn't alter the program.When compiling and executing the output is the following:
05 00 00 00 // hexdump() output
01 00 00 00
03 00 00 00
01 00 00 00
22 00 00 00
c6 00 00 00
f4 ff ff ff
f5 ff ff ff
e8 ee ee ff
-11 // "maximum" value
Which is correct since memcmp()
compares an string of bytes and doesn't care about types or sign so -11 = 0xfffffff5
is the maximum string of bytes in the array v[]
but at the same time is incorrect since -11
is not the maximum integer in the array.
Is there any way of getting the maximum integer of an array using this function?
Go down the qsort
route and require a custom comparator. Note that you absolutely don't need dynamic memory allocation in a function this simple:
#include <stdio.h>
void const *getmax(void const *data, size_t const count, size_t const elm_sz,
int (*cmp)(void const *, void const *)) {
char const *begin = data;
char const *end = begin + count * elm_sz;
char const *max = begin;
while (begin != end) {
if (cmp(max, begin) < 0) max = begin;
begin += elm_sz;
}
return max;
}
int int_cmp(void const *e1, void const *e2) {
int const i1 = *(int const *)e1;
int const i2 = *(int const *)e2;
if (i1 > i2) return 1;
if (i1 < i2) return -1;
return 0;
}
int main() {
int v[] = {5, 1, 3, 1, 34, 198, -12, -11, -0x111118};
int const *maximum = getmax(v, sizeof(v) / sizeof(*v), sizeof(*v), int_cmp);
printf("%d\n", *maximum);
}