简体   繁体   中英

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)
{   
    point p(100,21200); // segmentation fault!
    //point p(10,2);    // no segmentation fault!
    return 0;
}

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/free s 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&)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM