【发布时间】:2011-01-15 01:41:59
【问题描述】:
我有一个二叉搜索树类,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 向树添加内容,它使用指向根节点指针的指针。在我添加了新的“比较”成员后,这个功能就坏了。该函数开始如下(我添加了一些 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'中的地址,并且'node'是一个局部变量并且没有被取消引用;我不知道非法内存访问发生在哪里。我尝试将节点初始化为几个文字值(例如 NULL 或 0x1),但它们没有产生错误。只有在我将函数指针添加到类后它才失败,根据打印的内容,它被分配了正确的地址。是否与滥用模板有关?
顺便说一下,BSTree 模板是用类型名 int 和 const char* 实例化的,每个都有一个正确分配的不同比较函数(我认为)。我测试了他们的 add 函数,都产生了错误。
【问题讨论】:
-
我不认为您有可能被触发的 operator= 过载?
-
不。我没有重载任何运算符,我的类也没有超类:S
-
你为什么有
BSTNode<T> **node?我不明白为什么需要指向指针的指针。 -
指针到指针是为了能够修改节点。此函数向树中添加内容,它找到具有空指针的适当叶节点,并将该指针的值更改为新节点
-
看起来你的错误在别处。我测试了您的代码片段,它工作正常(也可以使用 valgrind 干净运行)。
标签: c++ pointers segmentation-fault function-pointers