Segmentaion fault (core dumped) error using qsort

I am getting a segmentation fault (core dumped) error using qsort.
Here are the structures I am using:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
struct team_info
{
    string name;
    int played, won, drawn, lost, points, goals_for, goals_against, diff;
};
struct tourney
{
    string tourney_name;
    int n_teams;
    int n_games;
    struct game
    {
        string home;
        int h_score;
        string away;
        int a_score;
    }g[1000];
    struct team_info team[30];
}t;


Here is the compare function I am using to compare the "points" field in struct team_info:

1
2
3
4
5
6
7
int compare_function_points(const void *a, const void *b)
{
    const struct team_info *sa = (struct team_info *)a;
    const struct team_info *sb = (struct team_info *)b;

    return sa->points - sb->points;
}


Here, is the qsort() call in my main() function:

qsort(t.team, t.n_teams, sizeof(t.team), compare_function_points);
Last edited on
1) You shall not use qsort for non-POD types. It wreaks their integrity. Also there is a great chance that you forgot to initialize n_teams. Is there any reason to use C function qsort instead of C++ std::sort?

2) Any reason to explicitely place struct before typename in C++?

You are trying to write C in C++. Do not do that.
Thanks for the reply.
What do you mean by non-POD types (excuse me, I am a beginner)?
I did initialize n_teams in the main() function.
Our teacher told us we could use qsort to sort an array of structs. I still did not get the reason not to use qsort in this case.
How could I use C++ std::sort in this case, that is, if I had to sort struct team_info teams[] by their "points"?
Is there any problem if I explicitly place struct before typename in C++?
Thanks in advance. :)
Is there any problem if I explicitly place struct before typename in C++?
No, but there is no need to do so in C++. Usually this is the first sign that person does not actually learning C++, but C with classes instead.

How could I use C++ std::sort in this case, that is, if I had to sort struct team_info teams[] by their "points"?
Same way like you would use qsort: create comparison function and pass it to std::sort. But without type erasure, unsafe cast and with compiler error checking:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
#include <algorithm>
#include <iostream>
#include <string>

struct team_info
{
    std::string name;
    int played, won, drawn, lost, points, goals_for, goals_against, diff;
};

struct tourney
{
    std::string tourney_name;
    int n_teams;
    int n_games;
    struct game
    {
        std::string home;
        int h_score;
        std::string away;
        int a_score;
    }g[1000];
    team_info team[30];
} t;

bool compare_points_less(const team_info& lhs, const team_info& rhs)
{
    return lhs.points < rhs.points;
}

int main()
{
    const int teams = 5;
    t.n_teams = teams;
    //initialize teams
    int scores[teams] = { 1, 8, 3, 5, 0};
    for(int i = 0; i < teams; ++i) {
        t.team[i].points = scores[i];
        std::cout << t.team[i].points << ' ';
    }
    std::cout << '\n';

    //sort
    std::sort(t.team, t.team + t.n_teams, compare_points_less);
    
    //display sorted
    for(int i = 0; i < t.n_teams; ++i) {
        std::cout << t.team[i].points << ' ';
    }
}


Our teacher told us we could use qsort to sort an array of structs.
Only trivial types like int. double, etc. string is not a trivial type and should not be sorted that way. Often strings contain a so-called small string optimisation which required them to contain pointer to itself. If you do a bitwise swap, those pointers start pointing to other object, completely breaking class and making it unusable and dangerous.

What do you mean by non-POD types
http://stackoverflow.com/questions/4178175/what-are-aggregates-and-pods-and-how-why-are-they-special/7189821#7189821
std::string is not trivial, so whole structure is not trivial either.

Edit: also standard explicitely says that qsort works only on trivial types:
The type of the elements of the array must be a trivial type, otherwise the behavior is undefined.
Last edited on
MiNiPaa, I can NOT thank you enough! I've been stuck with this all night.
There is one little question though.

bool compare_points_less(const team_info& lhs, const team_info& rhs)

I can't get why you used the ampersand (&) operator before lhs, and rhs?
This is passing by reference. Instead of copy of object we pass an object itself. Think about it as of safer pointer which does not need dereference
http://www.cplusplus.com/doc/tutorial/functions/#reference
http://www.learncpp.com/cpp-tutorial/73-passing-arguments-by-reference/
These ampersand(&) are used when we have to pass arguments by reference.
Topic archived. No new replies allowed.