4

I'm trying to use the qsort() to sort an array of object pointers (PointP = Point*) attached is the compare function and the sorting, The problem is that nothing happens and sorting doesn't occur.

int compareByAngleP(const void* elem1,const void* elem2) {
    PointP point1 = (PointP) elem1;
    PointP point2 = (PointP) elem2;
    if (abs(point1->getAngle() - point2->getAngle())>0.001)
    {
        return point1->getAngle() - point2->getAngle();
    }
    return  point1->getY() - point2->getY();
}

void sortArrayP(PointP* array, int size) {
    qsort(array,size, sizeof(PointP), compareByAngleP);
}
2
  • Have you tried it without the void*? Commented Dec 18, 2012 at 14:57
  • If array is indeed the base-address of a sequence of PointP, then your params are not setup correctly in your comparator. You're missing one level of indirection. Commented Dec 18, 2012 at 16:09

4 Answers 4

4

My advice would be to forget about std::qsort, favour plain old std::sort. Unlike std::qsort it is typesafe and in most implementations much faster.

std::sort(array, array+size, compareByAngleP);

And do rid of the void* in the compare function in favour of actual types.

Furthermore, if you are using C++11 and the array is local simply:

std::sort(std::begin(array), std::end(array), compareByAngleP);

Or even better just use a std::vector or other most approitaite container.

std::vector<Point> array { ... };
std::sort(array.begin(), array.end(), compareByAngleP);

Note

You may need to amend your comparison function so that it returns ​true if the first argument is less than the second. (or simply implement operator < for Point).

References

http://en.cppreference.com/w/cpp/algorithm/sort

http://en.cppreference.com/w/cpp/container/vector

Sign up to request clarification or add additional context in comments.

4 Comments

I'm not allowed to use c++11 or vectors :-(
and if i change void* to Point* then qsort() claims that the arguments don't match
:/, you can still use std::sort as I have shown in the first example.
@YuvalCohen I am suggesting you DON'T use std::qsort but std::sort.
3

There are several problems in your use of qsort and in your comparison function.

  1. qsort will use memcpy (or similar) to re-order the elements of the array. If your Point type has a copy-constructor (or a member that has one), then using qsort on it is asking for trouble (it results in Undefined Behaviour).

  2. Your compareByAngleP function is not suitable for sorting, because the relation it checks is not transitive. For example, if you have three points A, B and C, all with the same Y coordinate and respectively with the angles 10.000, 10.001 and 10.002, then compareByAngeP will indicate that A == B and B == C, but A != C, which can cause havoc for a sorting function.

Comments

1

Following qsort reference (http://en.cppreference.com/w/cpp/algorithm/qsort) 3rd parameter of qsort should be 'size of each element in the array in bytes' so instead

qsort(array,size, sizeof(PointP), compareByAngleP);

try

qsort(array,size, sizeof(PointP*), compareByAngleP);

Also you are implicity casting float to int (while returning value from comparing function). But:

(int)0.2 == 0

Comments

0

I think if you return bool instead of int from Compare function, then something different will happen.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.