将地址分配给指针指针会产生分段错误

时间:2011-01-15 01:42:00

标签: c++ pointers segmentation-fault function-pointers

我有一个二叉搜索树类BSTree。它曾经有一个成员,一个树的根节点。节点的类型由BSTNode结构定义。 但后来我添加了另一个成员,一个指向用于比较两个元素的函数的指针。那是问题开始的时候。

接口:

template <typename T>
struct BSTNode {
public:
    struct BSTNode<T> *left;
    struct BSTNode<T> *right;
    T key;
    BSTNode<T>(T element){ key = element;}
};

template <typename T>
class BSTree {
private:
    BSTNode<T> *root;
    int (*compare)(T el1, T el2); // this is the new member
public:
BSTree<T>(int (*cmp)(T el1, T el2)) {root = NULL; compare = cmp;}
    //...

向树添加内容的函数BSTree :: add使用指向根节点的指针。添加新的'compare'成员后,此功能中断。该函数从如下开始(它添加了一些printf行以找到崩溃的确切行):

功能定义:

template <typename T>
BSTNode<T>* BSTree<T>::add(T element) {
    BSTNode<T> **node;
    printf("&root = %p\n", &root);
    printf("node = %p\n", node); //must be NULL
    printf("compare = %p\n", (int(*)(T, T))compare); //address stored in fn pointer
    node = &root; /////////// THIS PART produces the segmentation fault. ////////
    printf("succeeded");
    //...

函数调用(在main中):

BSTree<int> bst(&stdcomp); //stdcomp is the integer compare function
bst.add(6);
//...

输出:

&root = 0x7fff5fbff8c0
node = 0x0
compare = 0x100001325
Segmentation fault

对我来说特别令人费解的是,分配失败了,即使它没有取消引用存储在我的指向指针'节点'中的地址,'node'是一个局部变量而且没有被解除引用;我不知道非法内存访问的位置。我试图将节点初始化为几个文字值(例如NULL或0x1),并且它们不会产生错误。它只是在我将函数指针添加到类后才失败,该类根据打印的内容分配了正确的地址。是否与滥用模板有关?

顺便说一句,BSTree模板用typenames int和const char *实例化,每个模板都有一个正确分配的不同比较函数(我认为)。我测试了他们的添加功能,两者都产生了错误。

2 个答案:

答案 0 :(得分:1)

printf("succeeded");调用之后,您的分段错误可能会发生,因为printf不包含换行符,并且您的输出可能处于行缓冲模式。所以字符串'succeeded'进入stdout缓冲区但没有出现在屏幕上。将stdout置于无缓冲模式,或在字符串中粘贴\n。或者更好的是,在每个printf之后粘贴fflush(stdout);,这样无论stdout缓冲模式如何,缓冲区都会被刷新。

答案 1 :(得分:0)

printf("compare = %p\n", (int(*)(T, T))compare);

这是未定义的行为 - printf的{​​{1}}需要指向%p的指针,但是您传递了一个函数指针。函数指针不能转换为void

我建议你在调试器中运行你的程序,看看它真的是你怀疑导致错误的任务。它可能是一些堆栈粉碎等。赋值本身应该只调用引用堆栈的操作。