C++Lambda分段错误

C++ Lambda segmentation fault

本文关键字:错误 分段 C++Lambda      更新时间:2023-10-16

以下代码产生分段错误,我不知道为什么:

    myTree<int> tree;
    tree.insert(10); // not important
    std::vector<int> v = tree.toVector(); // Segmentation fault

这是myTree代码(精简的,不可编译的,只足以理解它的内容):

template<class T> struct node {
    T key;
    node *left;
    node *right;
    int count;
    node(const T &k=T(), node *l=0, node *r=0) {
        key = k;
        left = l;
        right = r;
        count = 1;
    }
};
template<class T> class myTree {
public:
    myTree() {
        root = 0;
    }
    void traverseInOrder(void (*visitFunc)(node<T>* n)) {
        traverseInOrder(visitFunc, root);
    }
    std::vector<T> toVector() {
        std::vector<T> v;
        traverseInOrder([&](node<T>* n) {
            v.insert(v.end(), n->count, n->key);
        });
        return v;
    }
private:
    void traverseInOrder(void (*visitFunc)(node<T> *n), node<T> *n) {
        if (n == 0) {
            return;
        } else {
            if (n->left != 0) {
                traverseInOrder(visitFunc, n->left);
            }
            (*visitFunc)(n);
            traverseInOrder(visitFunc, n->right);
        }
    }
    node<T> *root;
};

分段故障发生在这一行:

v.insert(v.end(), n->count, n->key);

NetBeans变量窗口显示v为OUT_OF_SCOPE。

问题:我是否正确使用lambda

注:我使用的是g++(GCC)4.7.2(Cygwin)。

正如@Arkady在评论中提到的,有状态的lambda不会衰减为函数指针。修复方法是将traverseInOrder编写为一个模板,该模板接受一个可调用的对象

template<class Func>
void traverseInOrder(Func visitFunc)) {
    traverseInOrder(visitFunc, root);
}

或者,您可以更安全地输入,并为其提供一个接受std::function的签名,该签名返回void并接受node<T>*

void traverseInOrder(std::function<void(node<T>*)> visitFunc)) {
    traverseInOrder(visitFunc, root);
}