I tried to adapt this example from K&R (5.11, ANSI edition) to sort an array of ints but it crashes randomly and I can't figure why.
The original version sorted "lines" : char *lineptr[1000]
, I'm trying to sort int *p
or int p[4]
. I would like to keep the most generic parameters possible and I guess it's where my problem comes from.
#include <stdio.h>
#include <stdlib.h>
#define MAXNUMS 4
int numcmp(int* a, int* b);
void mqsort(void* v[], int left, int right, int (*comp)(void*, void*));
void swap(void* v[], int i, int j);
int numcmp(int* a, int* b) {
return *a - *b;
}
void swap(void* v[], int i, int j) {
printf("swap befor %d: %d, %d: %d\n", i, v[i], j, v[j]);
void* temp;
temp = v[i];
v[i] = v[j];
v[j] = temp;
printf("swap after %d: %d, %d: %d\n", i, v[i], j, v[j]);
}
void mqsort(void* v[], int left, int right, int (*comp)(void*, void*)) {
int i, last;
if (left >= right) {
return;
}
printf("left %d, right %d\n", left, right);
for (int j = 0; j < 4; j++) {
printf("%d, ", v[j]);
}
printf("\n");
swap(v, left, (left + right) / 2);
last = left;
for (i = left + 1; i <= right; i++) {
if ((*comp)(v[i], v[left]) < 0) {
++last;
swap(v, last, i);
}
}
swap(v, left, last);
for (int j = 0; j < 4; j++) {
printf("%d, ", v[j]);
}
printf("\n");
mqsort(v, left, last - 1, comp);
mqsort(v, last + 1, right, comp);
}
int main(void) {
int i;
/* doesn't work :( */
/* int* p; */
/* int* p_start; */
/* p_start = p = malloc(sizeof(int) * MAXNUMS); */
/* if (p == NULL) { */
/* printf("cannot allocate"); */
/* exit(1); */
/* } */
/* *(p + 0) = 1; */
/* *(p + 1) = 3; */
/* *(p + 2) = 5; */
/* *(p + 3) = 7; */
int p[MAXNUMS] = {1, 3, 5, 7};
for (i = 0; i < MAXNUMS; i++) {
printf("%d, ", p[i]);
}
printf("\n");
mqsort((void**)p, 0, MAXNUMS - 1, (int (*)(void*, void*))numcmp);
for (i = 0; i < MAXNUMS; i++) {
printf("%d, ", p[i]);
}
printf("\n");
/* free(p); */
/* free(p_start); */
return 0;
}
Here's a link to a working version and to the example itself, page 100.
I tried to bypass the comp
function completely, I also tried to change the pivot, I tried many versions of numcmp
like int numcmp(int a, int b)
, int numcmp(int *a, int *b)
but nothing works.
I always get random numbers after execution.
I really can't figure what's wrong and where do those numbers come from.
Obviously, when I just use mqsort(int* p, int start, int right)
and a comparison, it works fine :)
Your code has a minor error, which is that the array needs to consist of int *
rather than int
. So, in main, change
int p[MAXNUMS] = {1, 3, 5, 7};
to
int ip[] = {1, 3, 5, 7};
int *p[MAXNUMS] = {&ip[0], &ip[1], &ip[2], &ip[3]};
That and fixing the printfs to use correct parameters and formats fixes your code:
1, 3, 5, 7,
left 0, right 3
0x7ffe434e26e0, 0x7ffe434e26e4, 0x7ffe434e26e8, 0x7ffe434e26ec,
swap befor 0: 0x7ffe434e26e0, 1: 0x7ffe434e26e4
swap after 0: 0x7ffe434e26e4, 1: 0x7ffe434e26e0
swap befor 1: 0x7ffe434e26e0, 1: 0x7ffe434e26e0
swap after 1: 0x7ffe434e26e0, 1: 0x7ffe434e26e0
swap befor 0: 0x7ffe434e26e4, 1: 0x7ffe434e26e0
swap after 0: 0x7ffe434e26e0, 1: 0x7ffe434e26e4
0x7ffe434e26e0, 0x7ffe434e26e4, 0x7ffe434e26e8, 0x7ffe434e26ec,
left 2, right 3
0x7ffe434e26e0, 0x7ffe434e26e4, 0x7ffe434e26e8, 0x7ffe434e26ec,
swap befor 2: 0x7ffe434e26e8, 2: 0x7ffe434e26e8
swap after 2: 0x7ffe434e26e8, 2: 0x7ffe434e26e8
swap befor 2: 0x7ffe434e26e8, 2: 0x7ffe434e26e8
swap after 2: 0x7ffe434e26e8, 2: 0x7ffe434e26e8
0x7ffe434e26e0, 0x7ffe434e26e4, 0x7ffe434e26e8, 0x7ffe434e26ec,
1, 3, 5, 7,