c++qsortheap-corruption

Why do I get 0xC0000374 (STATUS_HEAP_CORRUPTION) error when using qsort() function of std in C++, and how do I fix it?


It's a simple C++ test code, it will just sort the student structs by their studentId which is an integer:

#include <iostream>

using namespace std;

struct student {
    int grade;
    int studentId;
    string name;
};

int studentIdCompareFunc(const void * student1, const void * student2);


int main()
{
    const int ARRAY_SIZE = 10;
    student studentArray[ARRAY_SIZE] = {
        {81, 10009, "Aretha"},
        {70, 10008, "Candy"},
        {68, 10010, "Veronica"},
        {78, 10004, "Sasha"},
        {75, 10007, "Leslie"},
        {100, 10003, "Alistair"},
        {98, 10006, "Belinda"},
        {84, 10005, "Erin"},
        {28, 10002, "Tom"},
        {87, 10001, "Fred"},
    };

    qsort(studentArray, ARRAY_SIZE, sizeof(student), studentIdCompareFunc);

    for (int i = 0; i < ARRAY_SIZE; i++)
    {
        cout << studentArray[i].studentId << " ";
    }

}


int studentIdCompareFunc(const void * voidA, const void * voidB)
{
    student* st1 = (student *) (voidA);
    student* st2 = (student *) (voidB);
    return st1->studentId - st2->studentId;
}

It prints the studentId integers as expected, but doesn't return zero, it returns -1072740940 (0xC0000374).

I tested by changing ARRAY_SIZE to 15, or increasing ARRAY_SIZE argument, but I still get the same result.

What's the cause of this error? How do I fix it?


Solution

  • qsort(studentArray, ARRAY_SIZE, sizeof(student), studentIdCompareFunc);
    

    qsort is a C library function and it knows absolutely nothing, whatsoever, about C++ classes. Like that std::string object in the structure this code is trying to sort. Undefined behavior, and hillarity, ensues.

    If the intent here is to write C++ code, then use the C++ equivalent, std::sort, which is a native C++ algorithm:

    #include <algorithm>
    
    // ...
    
    std::sort(studentArray, studentArray+ARRAY_SIZE,
       []
       (const auto &a, const auto &b)
       {
           return a.studentId < b.studentId;
       });