std::使用个人类排序返回分段错误

std::sort with personal class returns segmentation fault

本文关键字:返回 分段 错误 排序 std 人类      更新时间:2023-10-16

我对std::sort有一个小问题。

当我尝试使用带有 std::sort 的"<"函数的覆盖对分配的对象数组进行排序时,我得到了分段错误。

你可以在下面的玩具示例中看到问题:在我的class point中,我分配了一个个人对象数组key(特别是我为数组分配了内存v)。它的元素被初始化,然后我尝试对这个数组进行排序。

对于

较小的大小(对于数组v和要排序的数组),我没有收到任何错误,并且 valgrind 返回 noe。对于大尺寸,我得到一个分段错误,valgrind 输出了很多我不理解的错误。

你能帮我吗?

谢谢!

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;
}

类需要一个复制构造函数(或移动构造函数)和一个自定义赋值运算符,因为它们管理原始指针(资源)。否则,当 std::sort 执行pointkey对象的分配时,不会深层复制相应对象的数据,而只会复制指针。然后,析构函数最终会释放指向相同内存地址的指针的内存,从而导致未定义的行为(在 Linux/Unix 上,您经常会遇到段错误)。此外,删除这些malloc/free并用 new[]/delete[] 替换它们。或者更好的是,使用标准容器,如 std::vector .

请注意,某些编译器可能会在编译时捕获此问题。例如,带有-Weffc++的 gcc 会发出警告:

警告struct Foo具有指针数据成员 [-Weffc++] 但不会覆盖Foo(const Foo&)