2013-06-26 91 views
2

下面的代碼生成分段錯誤,我不知道爲什麼:C++的λ分段故障

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變量WINDO w表示v是OUT_OF_SCOPE。

問題:我正確使用lambda嗎?

注意:我正在使用g ++(GCC)4.7.2(Cygwin)。

+3

這是一個關於如何理解您編寫的代碼以及如何使用調試器的問題? – 2013-06-26 18:09:36

+0

t的價值是什麼?另外,嘗試插入()調用,並找出'this'的值在那裏。與上面定義'v'的棧幀中的'&v'比較。 – Arkadiy

+4

啊 - 這很有趣。根據這個(http://stackoverflow.com/a/2993349/3458)只有無狀態lambda可以作爲函數指針傳遞。你的國家不是無國籍的。 – Arkadiy

回答

5

正如@Arkadiy在評論中提到的,有狀態的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); 
} 
+1

或使用std :: function – Arkadiy

+0

非常感謝!對不起,沒有提供一個可編輯的例子。 – robert

+0

@Arkadiy tnx,已更新。 – TemplateRex