Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

std::sort with equal elements gives Segmentation fault

I have a container storing pointers. I am trying to sort these pointers in non-increasing order based on a data member in the corresponding objects pointed by the pointers. In my case, it is possible that many objects have the same value for that data member.

The following is a short code to illustrate the problem. The call to the sort function is giving a Segmentation fault. The weird thing about this is, if I have 16 elements in the container pointing to objects with same value for the double, the sort seems to work. But if I have 17 elements pointing to objects with same value, it gives a seg fault.

Can anyone please explain why this happens?

#include <iostream>
#include <algorithm>
#include <deque>

//some class
class A {
public:
    double a;
    A(double aval);
};

A::A(double aval) : a(aval) {}

//compare class
struct cmp_A : std::greater_equal<A*> {
    bool operator() (const A* x, const A* y) const;
} cmp_A_obj;

//greater_equal comparison
bool cmp_A::operator() (const A* x, const A* y) const {
    return (x->a >= y->a);
}

int main() {
    std::deque<A*> Adeque;
    //insert 17 A pointers into the container
    for(int i = 1; i<=17; i++) {
        Adeque.push_back(new A(5));
    }

    //This call to sort gives a Segmentation fault
    std::sort(Adeque.begin(), Adeque.end(), cmp_A_obj);

    for(std::deque<A*>::iterator i = Adeque.begin(); i!= Adeque.end(); i++) {
        std::cout << "|" << (*i)->a;
    }
    std::cout << std::endl;
}
like image 788
hash Avatar asked May 14 '13 05:05

hash


People also ask

What causes segmentation fault in C++?

A segmentation fault occurs when your program attempts to access an area of memory that it is not allowed to access. In other words, when your program tries to access memory that is beyond the limits that the operating system allocated for your program. Used to being properly initialized.

What kind of sort is std::sort?

The std::sort is a sorting function that uses the Introsort algorithm and have the complexity of O(N log(N)) where N= std::distance(first, last) since C++11 and the order of equal elements is not guaranteed to be preserved[3]. The gcc-libstdc++ also uses Introsort algorithm.

Why does std :: list need a special sort method?

std::list , being a linked list, cannot provide random access to its elements efficiently. That's why it provides its own specialized sort algorithm.

How to debug segmentation fault in C++?

1 Step 1: Compile it.#N#$ gcc -g Program1.cpp (in my case). 2 Step 2: Run it.#N#$ ./a.out (it is Object File)#N#If it shows Segmentation fault (core dumped) then follow following steps. 3 Step 3:Debug it More ...

What is segmentation fault?

– It is the runtime error caused because of the memory access violation. For Eg :-Stackoverflow, read violation etc.. In this example we will see how to find the segmentation error in the program. We will find which lines causes the segmentation fault error. Note :- I have used Linux distro – Ubuntu for this demonstration.

How do I get the line that causes segmentation error?

/home/logarithm/Desktop/Test Case/Miccl/core: No such file or directory. Then just type r and press the enter key . The output will be something like this showing the erroneous statement. Program received signal SIGSEGV, Segmentation fault. Now you have got the line that causes segmentation error.

What is the 3rd Argument of std sort?

Third argument of std::sort should be a function (or functional object) such that if compare (a, b) is true then compare (b, a) should be false, but your one isn't such. So your program is UB and can give any result. All true. But still does not really answer the question.


1 Answers

Your comparison must implement a strict weak ordering. Less than or equal does not satisfy this. It should be equivalent to "less than" or "greater than" as implemented in operators < and > for, say, integers.

Equality of elements is determined by applying this ordering twice:

(!cmp(a,b)) && (!cmp(b,a)); // if this is false, a == b
like image 145
juanchopanza Avatar answered Oct 12 '22 07:10

juanchopanza