C++ 将地址分配给指向指针的指针会导致分段错误

C++ 将地址分配给指向指针的指针会导致分段错误,c++,pointers,segmentation-fault,function-pointers,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<

我有一个二叉搜索树类,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;}
    //...
令我特别困惑的是,赋值失败,即使它没有取消引用存储在指向指针“node”的指针中的地址,“node”是一个局部变量,并且没有被取消引用;我不知道非法内存访问发生在哪里。我尝试将节点初始化为几个文本值(例如NULL或0x1),但它们没有产生错误。它只是在我添加了指向类的函数指针之后失败的,根据打印的内容,该类被分配了正确的地址。这与模板的滥用有关吗

顺便说一下,BSTree模板是用typenames int和const char*实例化的,每个模板都有一个正确分配的比较函数(我想)。我测试了它们的add函数,两个函数都产生了故障

printf("compare = %p\n", (int(*)(T, T))compare);
这是未定义的行为-
printf
%p
需要指向
void
的指针,但您传递了一个函数指针。函数指针不能转换为
void*


我建议您在调试器中运行程序,以查看是否确实是您怀疑的赋值导致了故障。可能是一些堆栈崩溃等。赋值本身应该只调用引用堆栈的操作。

分段错误可能发生在
printf(“成功”)之后调用,因为printf不包含换行符,并且您的输出可能处于行缓冲模式。因此字符串“successed”将进入标准输出缓冲区,但不会出现在屏幕上。将标准输出置于无缓冲模式,或在字符串中插入
\n
。或者更好的方法是,粘贴
fflush(stdout)
在每次printf之后刷新缓冲区,而不考虑stdout缓冲模式。

我不认为您有可能触发的operator=重载?没有。我没有重载任何操作符,我的类也没有超类:为什么有
BSTNode**node
?我不明白为什么需要指向指针的指针。指向指针的指针是为了能够修改节点。此函数向树中添加内容,它查找具有空指针的适当叶节点,并将该指针的值更改为新的nodeLooks,就像错误位于其他位置一样。我测试了你的代码片段,它工作得很好(也可以使用valgrind干净地运行)。结果表明,函数指针在大多数架构上都可以转换为void,但无论如何,这是一个好的观点。如果我看到一个没有明显的演员阵容,我仍然会发抖。然而,这看起来像一个指向成员函数的指针,它绝对是不可转换的,并且可能会使堆栈不平衡。是的,我知道这是一件可怕的事情,对不起。它在我的拱门中工作,它是指向非成员函数的指针,别担心,我肯定它不是一个胖指针——但我很清楚我不应该做这些假设。。。问题可能确实与堆栈有关,因为我几乎可以肯定是对局部变量的赋值导致程序崩溃。@user451963:几乎可以肯定?你是在调试器下运行的吗?崩溃的确切指令是什么?它在
add
的反汇编中的什么位置?或者他可以像其他人一样使用调试器。我不明白他为什么要打印像查找故障这样简单的东西。
BSTree<int> bst(&stdcomp); //stdcomp is the integer compare function
bst.add(6);
//...
&root = 0x7fff5fbff8c0
node = 0x0
compare = 0x100001325
Segmentation fault
printf("compare = %p\n", (int(*)(T, T))compare);