csortingmemcmp

Why are negative numbers greater than positive numbers?


I made my bubble sort program generic. I went on testing it and it was working well until I placed a negative number in the array, and I was surprised that it was pushed to the end, making it bigger than positive numbers.

Obviously memcmp is the reason, so why does memcmp() regard negative numbers greater than positive numbers?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void bubblesortA(void *_Buf, size_t bufSize, size_t bytes);

int main(void)
{
    size_t n, bufsize = 5;
    int buf[5] = { 5, 1, 2, -1, 10 };
    bubblesortA(buf, 5, sizeof(int));

    for (n = 0; n < bufsize; n++)
    {
        printf("%d ", buf[n]);
    }
    putchar('\n');

    char str[] = "bzqacd";
    size_t len = strlen(str);
    bubblesortA(str, len, sizeof(char));

    for (n = 0; n < len; n++)
    {
        printf("%c ", str[n]);
    }
    putchar('\n');
    return 0;
}

void bubblesortA(void *buf, size_t bufSize, size_t bytes)
{
    size_t x, y;
    char *ptr = (char*)buf;
    void *tmp = malloc(bytes);
    for (x = 0; x < bufSize; x++)
    {
        ptr = (char *)buf;
        for (y = 0; y < (bufSize - x - 1); y++)
        {
            if (memcmp(ptr, ptr + bytes, bytes) > 0)
            {
                memcpy(tmp, ptr, bytes);
                memcpy(ptr, ptr + bytes, bytes);
                memcpy(ptr + bytes, tmp, bytes);
            }
            ptr += bytes;
        }
    }
    free(tmp);
}

Edit:
So, How do I modify the program to make it compare correctly?


Solution

  • Answering OP's appended edit

    How can i modify the program to make it compare correctly?

    To compare two types as an anonymous bit pattern, memcmp() works fine. To compare two values of some type, code needs a compare function for that type. Following qsort() style:

    void bubblesortA2(void *_Buf,size_t bufSize,size_t bytes, 
        int (*compar)(const void *, const void *)))
    {
       ....
            // if(memcmp(ptr,ptr+bytes,bytes) > 0)
            if((*compar)(ptr,ptr+bytes) > 0)
       ....
    

    To compare int, pass in a compare int function. Notice that a, b are the addresses to the objects.

    int compar_int(const void *a, const void *b) {
      const int *ai = (const int *)a;
      const int *bi = (const int *)b;
      return (*ai > *bi) - (*ai < *bi);
    }
    

    To compare char, pass in a compare char function

    int compar_int(const void *a, const void *b) {
      const char *ac = (const char *)a;
      const char *bc = (const char *)b;
      return (*ac > *bc) - (*ac < *bc);
    }