std :: sort不适用于带有oveloaded<的用户定义对象操作者

时间:2017-04-03 17:58:55

标签: c++ algorithm sorting c++11 stl

我正在编写一个类来测试不同排序算法的效率(对于大学课程),我应该测试的算法是STL排序。为了衡量效率,我们定义了一个保持整数值的类Integer,并允许我们在每次比较或分配时增加一个全局变量。然后我有一个驱动程序类,它测试多个整数向量上的std :: sort调用。我已经超载了'<'我的Integer类中的运算符,它符合严格的弱排序(至少我很确定它的确如此)。然而,每当我调用sort时,我都会遇到分段错误。我真的无法弄清楚为什么会这样,任何帮助都会非常感激。谢谢!

Integer.cpp

#include "Integer.h"

int Integer_count;

//Default Constructor
Integer::Integer() {
    val = 0;
}

//Specified Constructor
Integer::Integer(int x) {
    val = x;
}

//Copy-Constructor
Integer::Integer(const Integer &cp) {
    Integer_count++;
    val = cp.val;
}

//Return the Integer's value
int Integer::value() {
    return val;
}

//Less-than (<) operator overload
bool Integer::operator < (const Integer& obj) const {
    Integer_count++;
    return (val < obj.val);
}

//Assignment (=) operator overload
void Integer::operator = (const Integer& obj) {
    Integer_count++;
    val=obj.val;
}

driver.cpp

#include <iostream>
#include <cstdlib>
#include <vector>
#include "Integer.h"
#include "Sorter.cpp"    
srand (time(NULL)); //Seed the random number generator

    std::vector<Integer> one;
    std::vector<Integer> two;
    std::vector<Integer> three;
    std::vector<Integer> four;
    std::vector<Integer> five;


    for(int i=0; i<10000; i++){
        one[i] = Integer(i);
        two[i] = Integer(10000-i);
        three[i] = Integer(rand() % (10000+1));
        four[i] = Integer(rand() % (10000+1));
        five[i] = Integer(rand() % (10000+1));
    }


    //Sort function called from the STL
    //Sorted Array
    std::sort(one.begin(), one.end());
    std::cout << "STL for Sorted Array: " << Integer_count << std::endl;

基本上,我认为std :: sort函数没有使用我的Integer类中的重载操作符,这会弄乱堆栈。我不确定这是错误,但似乎无法解决它。

3 个答案:

答案 0 :(得分:1)

您的vector [i]的值未分配。因此,访问超出范围的向量值(例如one[999999])会导致未定义的行为。

使用push_back() std:::vector 分配并为您的向量分配值:

for(int i=0; i<10000; i++){
    one.push_back(Integer(i));
    two.push_back(Integer(10000-i));
    three.push_back(Integer(rand() % (10000+1)));
    four.push_back(Integer(rand() % (10000+1)));
    five.push_back(Integer(rand() % (10000+1)));
}

这将解决分段故障。 至于排序,一旦你有价值。

std::sort(one.begin(), one.end()) sorts by default using operator< ,请保持原样。

答案 1 :(得分:0)

你没有在向量中推送/附加元素。在没有分配空间或推回的情况下,你不能以这种方式在向量中添加元素(由于错误的分配/数组超出范围,我的clang编译器会产生运行时错误)。请改用push_back

快速测试 -

std::vector<Integer> arr{Integer(1), Integer(4), Integer(3)};
sort(arr.begin(), arr.end());

// now print Integer_count

答案 2 :(得分:0)

std::vector::operator[]永远不会在容器中插入新元素,也不会执行边界检查(vector/operator_at)。如果您访问一个超出界限的元素会导致未定义的行为,这是您的情况。

您必须使用std::vector::emplace_backstd::vector::push_back,其他选项是使用构造函数explicit vector<T>(size_type count);构建容器count默认插入的T实例:

第一个选项:

std::vector<Integer> one;
one.reserve(10000);
std::vector<Integer> two;
two.reserve(10000);
std::vector<Integer> three;
three.reserve(10000);
std::vector<Integer> four;
four.reserve(10000);
std::vector<Integer> five;
five.reserve(10000);

for (int i = 0; i < 10000; ++i) {
    one.emplace_back(i);
    two.emplace_back(10000 - i);
    three.emplace_back(rand() % (10000+1));
    four.emplace_back(rand() % (10000+1));
    five.emplace_back(rand() % (10000+1));
}

第二个选项:

std::vector<Integer> one(10000);
std::vector<Integer> two(10000);
std::vector<Integer> three(10000);
std::vector<Integer> four(10000);
std::vector<Integer> five(10000);

for (int i = 0; i < 10000; ++i) {
    one[i] = Integer(i);
    two[i] = Integer(10000-i);
    three[i] = Integer(rand() % (10000+1));
    four[i] = Integer(rand() % (10000+1));
    five[i] = Integer(rand() % (10000+1));
}

std::sort(one.begin(), one.end())必须有效。