Question

I'm trying to define a set of template classes to represent search trees in C++.
In the find method i need to return the pointer of the node (represent as a pointer) that cointains the given key; in this way I'll reuse find method to implement insertion and deletion.

template <class K, class R>
struct Node {
    K key;
    R record;

    inline Node(K k, R r) {
        this->key = k;
        this->record = r;
    }
};

template <class K, class R>
struct BST_Node : public Node<K,R> {
    BST_Node<K,R> *sx;
    BST_Node<K,R> *dx;

    inline BST_Node(K key, R record)
    : Node<K,R>(key, record) {
        this->sx = NULL;
        this->dx = NULL;
    }

    BST_Node<K,R> **find(K k) {
        BST_Node<K,R> **p = k < this->key ? &this->sx : &this->dx;

        while (*p && k != (*p)->key)
             p = k < (*p)->key ? &(*p)->sx : &(*p)->dx;

        return p;
    }
/* other methods */
};

There is just a little problem: what if the key is in the root?
I cannot return &this because this, so what can I do?

The reason because i want to use pointer to pointer is that in this way I can return the address of a NULL pointer, so for insertion I can write something like that:

BST_Node<K,R> *insert(K k, R r) {
    BST_Node<K,R> **p = this->find(k);

    if (*p == NULL) //if the search fails
        *p = new BST_Node<K,R>(k, r);

    return *p;
}
Was it helpful?

Solution

You're not clear about. In your case, Pointer this has a type

BST_Node<K,R>* const

it means you can't change the direction(i don't know how to describe it specifically, like the address the pointer indicates..). If you returns

//BST_Node<K,R>**
return &this;

It means you can change the value of this by the returning value. It's not permitted. So an error occurs.

Why do you have to return a double pointer here?

I saw your edition, and i suppose you can return an NULL in function find() to indicate that you find the key at root. It will be a little complicate when you write a recursive find function, but since you're using loop, you can just add a if statement at the very first of the find function. Write like this in insert function:

if (p == NULL) //if returns the root
    /*do sth.*/

Just a tip, i don't ever save any data at root, and usually my tree root will be as long life time as the tree when i'm using a tree.

OTHER TIPS

I think you should re-read the note with more attention.

The problem is that &this is sitting somewhere in memory, and it points to the current object "you're in" (the current object scope your code is executing).
returning &this will point every time to the current object your code is in, which is not what you intended (it is actually depends on the compiler, I never read any "commitment" of the compiler to return any value in such a case, it is not in the C++ standard)

The solution is simple:

void* tothis = malloc(sizeof(void*)); // allocate memory that will survive leaving the current scope
tothis=this; // copy the current object memory address to the object
return &tothis; // return what you want

please don't forget to release the memory address of tothis afterwards (so you will not have a leak).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top