将节点添加到 bst 会导致值未定义

adding node to bst results in the value being undefined

我目前正在尝试重新实现地图,我有下面的代码。当我创建一个 class rb_tree 的对象并使用 class 中的插入函数插入数据时,一切都按预期工作,问题是一旦我尝试将一个值插入成员变量树class 地图使用地图 classes 插入,然后尝试打印树我得到未初始化的值。我的问题是为什么只有当我通过我的地图 class 插入时才会发生这种情况,而当我使用 rb_tree class 插入方法插入时不会发生这种情况?

#include <iostream>
#define BLACK 1
#define RED 0

namespace ft {
    template<typename T>
    class rb_tree_node {
    public:
        typedef rb_tree_node<T> *node_ptr;
        typedef rb_tree_node<T> self_type;
        typedef T               value_type;
        typedef T               *pointer;
        typedef T               &reference;

    public:
        rb_tree_node<T> *parent;
        rb_tree_node<T> *left;
        rb_tree_node<T> *right;
        int             color;
        value_type      *data;

    public:
        rb_tree_node() :
                parent(NULL),
                left(NULL),
                right(NULL),
                color(BLACK)
        {
            this->data = NULL;
        }

        rb_tree_node(value_type* v, int color = BLACK) :
                parent(NULL),
                left(NULL),
                right(NULL),
                color(color)
        {
            this->data = v;
        }

        rb_tree_node(const rb_tree_node &src) :
                                    parent(src.parent),
                                    left(src.left),
                                    right(src.right),
                                    color(src.color)
        {
            this->data = src.data;
        }

        ~rb_tree_node() {
        }
    };

    template<typename Key, typename Mapped, typename T>
    class rb_tree {
    public:
        typedef rb_tree_node<T>             *node_ptr;
        typedef rb_tree<Key, Mapped, T>     self_type;
        typedef T                           value_type;
        typedef T                           *pointer;
        typedef T                           &reference;
        typedef Key                         key_type;
        typedef Mapped                      mapped_type;

    private:
        node_ptr root;

    public:
        rb_tree() : root(NULL) {}

        rb_tree(const rb_tree &src) : root(src.root) {}

        ~rb_tree() {
            delete_tree(this->root);
        }

        void delete_tree(node_ptr node) {
                if (node->right!=NULL)
                    delete_tree(node->right);
                if (node->left!=NULL)
                    delete_tree(node->left);
                delete node;
        }

        node_ptr& get_root() {
            return this->root;
        }

        node_ptr find(key_type k) {
            node_ptr n = this->root;
            if (n == NULL)
                return NULL;
            else if (k == n->data->first)
                return n;
            else {
                while (n) {
                    if (n->data == NULL)
                        return NULL;
                    else if (k > n->data->first)
                        n = n->right;
                    else if (k < n->data->first)
                        n = n->left;
                    else
                        return n;
                }
            }
            return n;
        }

        void print(node_ptr p,int start)
        {
            start++;
            if (p->right != NULL)
            {
                print(p->right , start);
            }
            for (int i = 0; i <= start; i++)
            {
                std::cout<<"    ";
            }
            std::cout << ((p->data) ? p->data->first : 0)  << " " << ((p->color == 1) ? "B" : "R") << std::endl;
            if (p->left != NULL)
            {
                print(p->left, start);
            }
        }

        node_ptr insert_data(value_type data) {
            node_ptr node = new rb_tree_node<T>(&data, RED);
            if (this->root == NULL) {
                this->root = node;
                node->color = BLACK;
            }
            else {
                node_ptr x = this->root;
                node_ptr y = NULL;
                while (x && x->data) {
                    y = x;
                    if (x->data->first == node->data->first) {
                        std::cout << "Cannot add duplicate key" << std::endl;
                        delete node;
                        return x;
                    }
                    if (x->data->first > node->data->first) {
                        x = x->left;
                    }
                    else {
                        x = x->right;
                    }
                }
                x = node;
                node->parent = y;
                if (y->data->first > node->data->first) {
                    if (y->left)
                        delete y->left;
                    y->left = node;
                }
                else {
                    if (y->right)
                        delete y->right;
                    y->right = node;
                }
            }
            node->right = new rb_tree_node<T>();
            node->left = new rb_tree_node<T>();
            node->right->parent = node;
            node->left->parent = node;
            return (node);
        }
    };

    template < class Key,                                                   // map::key_type
            class T,                                                        // map::mapped_type
            class Compare = std::less<Key>,                                 // map::key_compare
            class Allocator = std::allocator<std::pair<const Key,T> >       // map::allocator_type
    >
    class map {
    public:
        typedef Key                                     key_type;
        typedef T                                       mapped_type;
        typedef std::pair<const key_type,mapped_type>   value_type;
        typedef Compare                                 key_compare;
        typedef Allocator                               allocator_type;
        typedef std::size_t                             size_type;
        typedef std::ptrdiff_t                          difference_type;
        typedef value_type                              &reference;
        typedef const value_type                        &const_reference;
        typedef value_type                              *pointer;
        typedef const value_type                        *const_pointer;

        typedef ft::rb_tree<Key, T, value_type>     bst;
        typedef ft::rb_tree_node<value_type>        *node_pointer;
        typedef const ft::rb_tree_node<value_type>  *const_node_pointer;

    private:
        bst             *tree;
        size_type       t_size;
        allocator_type  allocator;
        key_compare     key_cmp;

    public:
        explicit map (const key_compare& comp = key_compare(),
                      const allocator_type& alloc = allocator_type()) {
            key_cmp = comp;
            allocator = alloc;
            this->tree = new bst();
            this->t_size = 0;
        }

        ~map() {
            delete this->tree;
        }

        void insert (const value_type& val) {
            node_pointer n = this->tree->find(val.first);
            if (n) {
                return ;
            }
            else {
                n = this->tree->insert_data(val);
                this->t_size++;
                return ;
            }

        }

        void clear() { // this probs doesnt work
            node_pointer node = this->tree.min_val();
            node_pointer tmp = NULL;
            while (node->next()) {
                tmp = node;
                node = node->next();
                delete tmp;
            }
            if (node)
                delete node;
        }

        void print() {
            if (this->tree->get_root() != NULL)
                this->tree->print(this->tree->get_root(), 1);
        }

    };
}

int main() {
    ft::rb_tree<int, std::string, std::pair<int, std::string> > bst;
    bst.insert_data(std::pair<int, std::string>(61, "hola"));
    bst.insert_data(std::pair<int, std::string>(52, "sup"));
    bst.insert_data(std::pair<int, std::string>(85, "gme"));
    bst.print(bst.get_root(), 1);

    ft::map<int, std::string> m;
    std::pair<int, std::string> v = std::pair<int, std::string>(1000, "one");
    m.insert(v);
    m.print();
    v = std::pair<int, std::string>(15000, "two");
    m.insert(v);
    m.print();

    return (0);
}

当我运行上面的代码时,我得到以下输出

                    0 B
                85 R
                    0 B
            61 B
                    0 B
                52 R
                    0 B
                0 B
            1665161504 B
                0 B
Cannot add duplicate key
                0 B
            1665161504 B
                0 B

如您所见,使用 rb_tree class 将节点添加到树中效果很好,但通过映射 class 执行此操作会导致最后两个输出未定义。我已经坚持了将近一个星期,非常感谢任何帮助。

value_type      *data;

您绝对不希望此处有指针。

node_ptr node = new rb_tree_node<T>(&data, RED);`. 

该指针现在指向调用函数的局部变量。轰!