私はバイナリ検索ツリークラスBSTreeを持っています。これは、ツリーのルートノードである単一のメンバーを持つことでした。ノードのタイプは、BSTNode構造体によって定義されます。 しかし、私は別のメンバー、2つの要素を比較するために使用される関数へのポインタを追加しました。それは問題が始まったときです。ポインタへのポインタの代入によってセグメント化エラーが発生する
インタフェース:
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 ::追加し、ツリーにものを追加して、ルートノードへのポインタへのポインタを使用しています。私は新しい '比較'メンバーを追加した後、この関数は壊れました。
関数定義:
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");
//...
ファンクションコール(メインで):
BSTree<int> bst(&stdcomp); //stdcomp is the integer compare function
bst.add(6);
//...
次のように関数が始まる(それは私がクラッシュした正確なラインを見つけるために、追加いくつかのprintfラインを持っています)出力:
&root = 0x7fff5fbff8c0
node = 0x0
compare = 0x100001325
Segmentation fault
特に困惑しているのは、割り当てが失敗し、 hは、ポインタへのポインタ 'node'に格納されているアドレスを逆参照しません。また、 'node'はローカル変数であり、逆参照されません。私は、不正なメモリアクセスがどこで発生するのかわかりません。ノードをいくつかのリテラル値(NULLや0x1など)に初期化しようとしましたが、エラーは発生しませんでした。私はクラスに関数ポインタを追加した後に失敗しただけです。クラスには、印刷されたものに応じて正しいアドレスが割り当てられます。テンプレートの誤用とは何か関係がありますか?
ちなみに、BSTreeテンプレートはtypemames intとconst char *でインスタンス化されていますが、それぞれが正しく割り当てられた異なる比較関数を持っています(私は思っています)。私はそれらの追加機能をテストし、両方とも障害を生成しました。 printf
の%p
がvoid
へのポインタを期待していますが、関数ポインタを渡す -
私は演算子=のオーバーロードが発生しているとは思わないでしょうか? – Aron
nope。私はすべての演算子をオーバーロードしていないし、私のクラスはスーパークラスを持っていない:S –
なぜ 'BSTNode ** node'があるのですか?ポインターからポインタへのポインタが必要な理由はわかりません。 –