简体   繁体   English

C ++指针不起作用?

[英]C++ pointers not working?

I have a problem with working with c++ pointers. 我在使用c ++指针时遇到问题。 I'm trying to code a splay tree by using a Node struct and Tree struct. 我正在尝试通过使用Node结构和Tree结构对八叉树进行编码。 However, upon testing, I have encountered a problem. 但是,经过测试,我遇到了一个问题。 The portion of my code that's not working is below: 我的代码无法正常工作的部分如下:

struct Node {
    Node* l, *r, *p;
    int v;
    Node() {}
    Node(int _v, Node* _p) : v(_v), p(_p) {}
};

struct Tree {
    Node* root;

    Tree() : root(0) {}

    //...

    void insert(int k) {
        if (!root) {
            root = new Node(k, 0);
            return;
        }
        Node* cur = new Node();
        cur->v = root->v;
        while (1) {
            int x = cur->v;
            cout << x << endl;
            return;
            if (k <= x) {
                //cout << x << endl;
                //return;
                if (!cur->l) {
                    cur->l = new Node(k, cur);
                    //splay(cur->l);
                    return;
                } else cur = cur->l;
            } else {
                if (!cur->r) {
                    cur->r = new Node(k, cur);
                    //splay(cur->r);
                    return;
                } else cur = cur->r;
            }
        }
    }

    //...
};

int main() {
    Tree t = Tree();
    t.insert(1);
    t.insert(5);
    return 0;
}

First, I inserted a node with value 1 in the tree; 首先,我在树中插入了一个值为1的节点; since there was no root, the tree assigned its root as a new node with value 1. Then, when I inserted 5 into the tree, something weird happened. 因为没有根,所以树将其根分配为值为1的新节点。然后,当我在树中插入5时,发生了一些奇怪的事情。 If you leave the code like it is (keeping the first cout), then it will print out 1 for x. 如果您按原样保留代码(保留第一个cout),则它将为x打印1。 However, if you comment out the first cout and return and uncomment the second cout and return, you'll find that it prints out a random garbage number for x, even though no modifications were made. 但是,如果注释掉第一个cout并返回并取消注释第二个cout并返回,则您会发现即使没有进行任何修改,它也会打印出x的随机垃圾编号。 Can somebody tell me what's wrong? 有人可以告诉我怎么了吗?

C++ does not initialize class members automatically. C ++不会自动初始化类成员。

struct Node {
    Node* l, *r, *p;
    int v;
    Node() {}
    Node(int _v, Node* _p) : v(_v), p(_p) {}
};

When you create a new node in your code C++ allocates a piece of memory for the Node but it will not clear it. 当您在代码中创建一个新节点时,C ++会为该节点分配一块内存,但不会清除它。 So the values of l, r & p will be whatever was there. 因此,l,r和p的值将是存在的值。
In your algorithm the tests: if (!cur->r) & (!cur->l) currently fail because there is uninitialized garbage in the nodes and not NULL . 在您的算法中,测试( if (!cur->r)(!cur->l)当前失败,因为节点中存在未初始化的垃圾,而不是NULL
As a result when you try to insert the second node the algorithm thinks that there is a valid node to the right of root. 结果,当您尝试插入第二个节点时,该算法认为根节点的右边有一个有效节点。 And tries to read the memory there and the value there which is the junk x you see. 并尝试读取那里的内存和那里的值,即您看到的垃圾x。 Depending on the value of the junk it may also crash for some people running the code :) 根据垃圾值的不同,运行某些代码的人也可能会崩溃:)

Also I'm 99.9% certain that Node* cur should be a pointer to a Node in the tree and not a new node so: Node* cur = new Node(); cur->v = root->v; 我也99.9%确信Node* cur应该是树中节点的指针,而不是新节点,因此: Node* cur = new Node(); cur->v = root->v; Node* cur = new Node(); cur->v = root->v; is wrong and should be Node* cur = root; 是错误的,应为Node* cur = root;

Proper Initialization - In c++11 you can do: 正确的初始化-在c ++ 11中,您可以执行以下操作:

struct Node {
    Node* l = nullptr;
    Node *r = nullptr;
    Node *p = nullptr;
    int v   = 0;
    Node() {}
    Node(int _v, Node* _p) : v(_v), p(_p) {}
};

Otherwise 除此以外

struct Node {
    Node* l;
    Node *r;
    Node *p;
    int v;
    Node() : l(NULL), r(NULL), p(NULL), v(0){}
    Node(int _v, Node* _p) : l(NULL), r(NULL), p(_p), v(_v) {}
};

You should initialize members of a class in the same order they were defined. 您应该按照定义它们的顺序来初始化类的成员。

Now there are a lot of other things that are problematic in the code: 现在,代码中还有很多其他问题:

  • Tree seems to allocate lots of nodes but does not release any memory. 树似乎分配了很多节点,但没有释放任何内存。 (easiest to just use unique_ptr for l and r and root Node) (最简单的方法是对l和r以及根节点仅使用unique_ptr
  • Is tree the owner of subnodes? 树是子节点的所有者吗? Or should it be Node owning and allocating left and right? 还是应该由Node拥有并左右分配? (goes away if you use std::unique_ptr for left and right) (如果您使用std::unique_ptr左右,则会消失)
  • You are not initializing the members in the order they are defined. 您没有按照定义的顺序初始化成员。 This can cause all kind of errors. 这可能会导致各种错误。 (since the compiler reorders initialization without telling you) (因为编译器不通知您就对初始化进行了重新排序)
  • Node and Tree handle raw pointers but do not define a proper operator=, copy ctor (or delete them) (goes away if you use unique_ptr) 节点和树处理原始指针,但未定义适当的operator =,复制ctor(或删除它们)(如果使用unique_ptr,则消失)
  • Tree is missing a dtor to clean allocated memory (goes away if you use unique_ptr) 树缺少用于清理分配的内存的dtor(如果使用unique_ptr,则消失)

  • 声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

     
    粤ICP备18138465号  © 2020-2024 STACKOOM.COM