使用c / c ++中的用户定义函数对大向量进行排序

时间:2015-02-26 16:41:50

标签: c++ c

我编写了以下代码,用于根据我的排序标准对两个向量进行排序:

typedef pair<unsigned, pair<vector<unsigned>, vector<unsigned> > > Elem;
bool bucketComparator(const Elem& a, const Elem& b) {
    //find the min and max of "a" and "b"
    // return true if a should go before b in the sort
    unsigned minA,maxA;
    unsigned minB,maxB;
    if((a.second.first).size()<=1){
        minA=maxA=*((a.second.first).begin());
    } else{
        minA=*std::min_element((a.second.first).begin(),(a.second.first).end());
        maxA=*std::max_element((a.second.first).begin(),(a.second.first).end());
    }
    if((b.second.first).size()<=1){
        minB=maxB=*((b.second.first).begin());
    } else{
        minB=*std::min_element((b.second.first).begin(),(b.second.first).end());
        maxB=*std::max_element((b.second.first).begin(),(b.second.first).end());
    }
    if((minA<=minB)&&(maxA<=maxB)){
        return true;
    } else{
        return false;
    }
}
main()
{
   vector<Elem> A;
   //initializing vector A with values
   std::sort(A.begin(), A.end(), bucketComparator);
   //further computation using vector A
}

错误:大数据的分段错误。

当向量A的大小为223080或更大时,我发现我正在获得分段错误。但是当向量A的大小小于100时,代码运行良好。由于我在64GB RAM上运行代码,因此无法理解其原因。有人可以帮我解决这个问题。

此外,当我在linux上运行top命令时,我发现由于分段错误,程序在停止之前甚至不会消耗0.1%(64GB)的可用RAM。

我甚至试图通过首先使用std :: sort和冒泡排序对矢量进行排序来找到max和min - 但我仍然得到相同的错误。

我正在运行以下版本的gcc:gcc(Ubuntu / Linaro 4.6.3-1ubuntu5)4.6.3

我是否可以通过某种方式编写程序,以便根据我使用的排序条件对大型向量进行排序:bucketComparator。我对c和c ++都很好。

此外,当我执行简单的std :: sort:

时,代码不会出现分段错误
std::sort(A.begin(), A.end());

3 个答案:

答案 0 :(得分:1)

我唯一能看到可能错误的是您取消引用std::min_elementstd::max_element返回的内容,而不检查它们返回的是什么<vector>.end(),这是可能的。当某个指针在某个地方被取消引用时,它几乎总是会发生。如果它不应被解除引用。

例如,如果向量为空,std::min_elementstd::max_element将返回<vector>.end(),您将解除引用。

答案 1 :(得分:1)

如果向量a.second.firstb.second.first为空,则程序将在取消引用begin()调用的迭代器时崩溃。

bool bucketComparator(const Elem& a, const Elem& b) {
    //find the min and max of "a" and "b"
    // return true if a should go before b in the sort
    unsigned minA,maxA;
    unsigned minB,maxB;

    const vector<unsigned> &vecA = a.second.first;
    const vector<unsigned> &vecB = b.second.first;

    //check if vectors empty
    if (vecA.empty()){
        return true;
    }
    if (vecB.empty()){
        return false;
    }

    if((vecA).size()==1){
        minA=maxA=*((vecA).begin());
    } else{
        minA=*std::min_element((vecA).begin(),(vecA).end());
        maxA=*std::max_element((vecA).begin(),(vecA).end());
    }
    if((vecB).size()==1){
        minB=maxB=*((vecB).begin());
    } else{
        minB=*std::min_element((vecB).begin(),(vecB).end());
        maxB=*std::max_element((vecB).begin(),(vecB).end());
    }
    if((minA<=minB)&&(maxA<=maxB)){
        return true;
    } else{
        return false;
    }
}

我还建议使用本地const引用变量来提高代码的可读性和性能。

答案 2 :(得分:1)

std::sort的文档描述了比较器属性:

  

二进制函数,它接受范围中的两个元素作为参数,并返回一个可转换为bool的值。返回的值表示作为第一个参数传递的元素是否被认为是在它定义的特定 严格弱排序 中的第二个参数之前。

     

该函数不得修改其任何参数。

     

这可以是函数指针或函数对象。

严格的弱排序由以下特征(source)定义:

Irreflexivity                   f(x, x) must be false.
Antisymmetry                    f(x, y) implies !f(y, x)
Transitivity                    f(x, y) and f(y, z) imply f(x, z).
Transitivity of equivalence     Equivalence (as defined above) is transitive: if x is equivalent to y and y is equivalent to z, then x is equivalent to z.

如果xy都为假,则认为两个元素f(x,y)f(y,x)是等效的。

您定义的功能不遵循这些规则,特别是它违反了无反射性和反对称性;当minA == minB && maxA == maxB时,bucketComparator(a,b)bucketComparator(b,a)都会产生true值。由于仿函数无效,因此会导致未定义的行为。

您需要更新您的仿函数以提供严格的弱排序。一种解决方案可能是改变声明:

if((minA<=minB)&&(maxA<=maxB))

if( minA <= minB && maxA < maxB )