I was writing a code which is using qsort from <stdlib.h>. While my Code is absolutly working fine for 8 elements in of the Array that will be sorted it doesnt for more then 10 elements. I`ve no idea why it doesnt work, I hope you can help me out.
Talking about the Problem: I was trying to sort a float Array with 10 Elements. On the fact this didnt work I tried to make it easier by using only Integers. While i was tesing it I realised that qsort works pretty good by using 8 elements or less for the array. When i was using more then 8 elements it wasnt working at all. Some elements (always the same ones) were sorted others werent. at all they werent listed correct. So I tried other codes to solve the problem but not a single code changed something.
#include <stdio.h>
#include <stdlib.h>
int CompareFloat(const void* pcv1, const void* pcv2);
int CompareIntegers(const void* pcv1, const void* pcv2);
int main()
{
int aiArr[10] = { 10,9,8,7,5,6,4,2,3,1};
int aiArr2[8] = { 8,7,6,5,4,2,3,1 };
float afArr[8] = { 5.0f, 4.611f, 4.61f, 4.1f, 4.0f, 10.0f, 1.9f, 1.8f };
for (int i = 0; i < 8; i++)
{
printf("%f\t", afArr[i]);
}
puts("\n");
for (int i = 0; i < 10; i++)
{
printf("%i\t", aiArr[i]);
}
puts("\n");
for (int i = 0; i < 8; i++)
{
printf("%i\t", aiArr2[i]);
}
qsort(aiArr2, 8, sizeof(int), CompareIntegers);
qsort(aiArr, 10, sizeof(int), CompareIntegers);
qsort(afArr, 8, sizeof(float), CompareFloat);
puts("\n");
for (int i = 0; i < 8; i++)
{
printf("%f\t", afArr[i]);
}
puts("\n");
for (int i = 0; i < 10; i++)
{
printf("%i\t", aiArr[i]);
}
puts("\n");
for (int i = 0; i < 8; i++)
{
printf("%i\t", aiArr2[i]);
}
return 0;
}
int CompareFloat(const void* pcv1, const void* pcv2)
{
int iRet;
float* pf1 = (float*)pcv1;
float* pf2 = (float*)pcv2;
if (*pf1 < *pf2)
{
iRet = -1;
}
if (*pf1 > *pf2)
{
iRet = 1;
}
else
{
iRet = 0;
}
return iRet;
}
int CompareIntegers(const void* pcv1, const void* pcv2)
{
int iRet;
int* pi1 = (int*)pcv1;
int* pi2 = (int*)pcv2;
if (*pi1 < *pi2)
{
iRet = -1;
}
if (*pi1 > *pi2)
{
iRet = 1;
}
else
{
iRet = 0;
}
return iRet;
}
Output (cutt some 0):
1.8000 1.9000 4.0000 4.1000 4.6100 4.6110 5.0000 10.0000
1 3 2 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8
Expected Output (cut some 0):
1.8000 1.9000 4.0000 4.1000 4.6100 4.6110 5.0000 10.0000
1 2 3 4 5 6 7 8 9 10
1 2 3 4 5 6 7 8
I was reading a lot of code and more informations about qsort but its not working fine. The elemts of the bigger array arent sorted, like they should (I think so).
In your compare functions, you left off else
in your second if
.
You have:
if (*pi1 < *pi2)
iRet = -1;
if (*pi1 > *pi2)
iRet = 1;
else
iRet = 0;
Consider what happens when *pi1 < *pi2
. The first if
is true, so we set iRet = -1
. We then go on to the second if
(this is the bug). The second if
is false, so we set iRet = 0
. Thus we end up returning 0 instead of the correct result -1.
A three-way test should instead look like:
if (*pi1 < *pi2)
iRet = -1;
else if (*pi1 > *pi2) // note else here
iRet = 1;
else
iRet = 0;
so that only one of the branches ever executes.
Alternatively, use an "early return":
if (*p1 < *p2)
return -1;
if (*p1 > *p2)
return 1;
return 0;