c ++ std :: set insert导致分段错误

时间:2011-03-24 20:17:36

标签: c++ stl set

全部 -

我无法弄清楚为什么这段代码会导致分段错误......任何帮助都会很棒。

#include <iostream>
#include <set>

using namespace std;

class A{
public:
    int _x;

    A(int x){
        _x = x;
    }
};

bool fncomp(A a1, A a2){
    return a1._x < a2._x;
}

int main(){
    bool(*fn_pt)(A,A) = fncomp;

    set<A, bool(*)(A,A)> testSet;
    for(int i=0; i<10; i++){
        cout << i << endl;
        A a(i);
        testSet.insert(a);
    }
}

输出结果为:

0
1
Segmentation Fault

2 个答案:

答案 0 :(得分:8)

好吧,看看你的代码。你声明了一个函数fncomp,但你真的在任何地方使用该函数吗?您使用它初始化fn_pt,但fn_pt未在任何地方使用。你觉得这不奇怪吗?您如何期望testSet对象知道您希望它使用fncomp作为比较器,如果您从未要求您的设置对象使用该功能?

您使用普通函数指针类型testSet声明了您的集合bool(*)(A,A)作为比较器类型。那是比较器的类型。现在,您必须通过构造函数参数

将比较器的实际传递给您的set对象
set<A, bool(*)(A,A)> testSet(fn_pt);

set<A, bool(*)(A,A)> testSet(fncomp);

(你真的不需要那个中间指针fn_pt)。

您忘了这样做,并且set对象使用比较器的默认构造函数参数值,在本例中是一个空指针。因此,每次testSet对象尝试比较两个元素时,它都会通过空指针执行函数调用。难怪它崩溃了。

答案 1 :(得分:1)

您是否收到有关未使用变量fn_pt的编译器警告?

变量testSet具有指定类型bool(*)(A,A)的内部比较器。由于您没有初始化它,因此默认初始化为NULL。因此,当testSet尝试插入A(1)时,它会尝试调用null函数指针来确定哪个顺序正确。

你可能意味着:

set<A, bool(*)(A,A)> testSet(fn_pt);