user85022 February 2016

std::sort with personal class returns segmentation fault

I have a small problem with std::sort.

When I try to sort an allocated array of objects using the override of the "<" function with std::sort, I get a segmentation fault.

You can see the problem here below in a toy example: In my class point, I allocate an array of personal objects key (especially I allocate the memory for an array v). Its elements are initialized, and then I try to sort this array.

With small sizes (for the array v and the array to sort), I get no error, and valgrind returns none. For big sizes, I get a segmentation fault, and valgrind outputs a lot of errors I don't understand.

Could you help me?

Thanks!

using namespace std;
#include <stdlib.h>
#include <iostream>
#include <algorithm>
class key
{
    public :
        int size;
        double *v, f;

        key() {}
        key(const key & k)
        {
            size = k.size;
            f = k.f;
            v = (double*)malloc(size*sizeof(double));
            for(int i=0;i<size;i++)
                v[i]=k.v[i];
        }
        ~key()
        {
            free(v);
        }
        bool operator<(const key& other) const
        {
            return f<other.f;
        }
        void init(int s)
        {
            size = s;
            v    = (double*)malloc(size*sizeof(double));
            for(int i=0;i<size;i++)
                v[i]=((double)rand()/(RAND_MAX));
        }
};
class point
{
    public :
        key *k;

        point() {}
        point(int param1, int param2)
        {
            k = (key*)malloc(param1*sizeof(key));
            for(int i=0;i<param1;i++)
            {
                k[i].init(param2);
                k[i].f=param1-i;
            }
            std::sort(k,k+param1);
            free(k);
        }
};


int main(int argc, char **argv)
{   
          

Answers


vsoftco February 2016

Your classes need a copy constructor (or a move constructor) and a custom assignment operator because they manage raw pointers (resources). Otherwise when std::sort performs assignments of your point or key objects, the corresponding objects' data is not deep copied, but only the pointers are copied. Your destructor then ends up freeing the memory for pointers that point to the same memory address, which results in undefined behaviour (you'll often get a segfault on Linux/Unix). Also, remove those malloc/frees and replace them by new[]/delete[]. Or better, use standard containers like std::vector.

Note that some compilers can catch this issues at compile time. For example, gcc with -Weffc++ spits out an warning:

warning: struct Foo has pointer data members [-Weffc++] but does not override Foo(const Foo&)

Post Status

Asked in February 2016
Viewed 3,489 times
Voted 8
Answered 1 times

Search




Leave an answer