由于比较功能导致的分段错误

时间:2015-12-24 02:17:29

标签: c++ segmentation-fault

我尝试在spoj上解决这个问题。 http://www.spoj.com/problems/BUSYMAN/

虽然我能够解决它,但我得到了一个非常奇怪的错误。我试过了解它的原因却失败了。我有两个代码。

/////////////////////////////////////////////// ////

#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;

class activity
{
    public:
    int start,end;
};

bool comp(activity p, activity q)
{
    if(p.end<q.end)return true;
    if(p.end==q.end&&p.start<=q.start)return true;
    return false;
}

int main()
{
    int t;
    cin>>t;
    vector<activity> v;
    for(int i=0;i<t;i++)
    {
        int n;
        cin>>n;

        v.resize(n);
        for(int j=0;j<n;j++)cin>>v[j].start>>v[j].end;
        sort(v.begin(),v.end(),comp);
        int ans=0,currend=0;
        for(int j=0;j<n;j++)
        {
            if(v[j].start>=currend){ans++;currend=v[j].end;
        }

    }
    cout<<ans<<endl;
    }
}

/////////////////////////////////////////////

#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;

class activity
{
    public:
    int start,end;
};

bool comp(activity p, activity q)
{
    if(p.end<q.end)return true;
    if(p.end==q.end&&p.start>=q.start)return true;
    return false;
}

int main()
{
    int t;
    cin>>t;
    int n;
    vector<activity> v;
    for(int i=0;i<t;i++)
    {
        cin>>n;
        v.resize(n);
        for(int j=0;j<n;j++)
            cin>>v[j].start>>v[j].end;
        sort(v.begin(),v.end(),comp);
        int ans=0,currend=0;
        for(int j=0;j<n;j++)
        {
            if(v[j].start>=currend)
            {
                ans++;currend=v[j].end;
            }
        }
        cout<<ans<<endl;
    }
}

//////////////////////////////

我的问题是第一个在spoj上给出了分段错误而第二个没有。两者之间的唯一区别是比较功能。我碰巧用两种不同的方式来定义比较函数的第二个语句。但它在第一种情况下给我分段错误,但在第二种情况下没有。

enter image description here enter image description here

enter image description here 在此输入图像描述 The codes

在上面的两幅图中,有两个代码分别具有提交ID,第三个代码显示一个故障,而不是其他。您也可以使用我的spoj配置文件中的提交ID进行验证。

2 个答案:

答案 0 :(得分:4)

由于bool comp(activity p, activity q)不符合Compare的要求,请参阅std::sort

应该是这样的:

bool comp(const activity& p, const activity& q)
{
    return p.end < q.end || (p.end ==q.end && p.start < q.start);
}

struct comp {
    bool operator()(const activity& p, const activity& q) const
    {
        return p.end < q.end || (p.end ==q.end && p.start < q.start);
    }
};

struct comp {
    bool operator()(const activity& p, const activity& q) const
    {
        return std::tie(p.end, p.start) < std::tie(q.end, q.start);
    }
};

答案 1 :(得分:0)

C ++的规则是std::sort的比较器必须给出strict weak ordering

因此,比较器必须为相等的元素返回false。不过这个测试:

if(p.end<q.end)return true;
if(p.end==q.end&&p.start<=q.start)return true;
return false;
如果元素相等,

返回true,因此这是一个无效的比较器。

第二次尝试:

if(p.end<q.end)return true;
if(p.end==q.end&&p.start>=q.start)return true;
return false;

这有同样的问题,也会导致未定义的行为。

当代码具有未定义的行为时,您无法从观察到的行为中推断出任何内容,只是偶然(可能取决于您的编译器特定的排序算法选择的一些细节)关于您获得的行为。

在第一个比较器中将<=更改为<将产生一个有效的比较器,其排序顺序为end和start ascending。