Vector返回负大小的c ++

时间:2018-05-02 14:05:15

标签: c++ pointers recursion tree cout

对于exercize,我想打印出一个基于Node对象的树数据结构。这意味着,每个对象都有一个矢量节点,它再次保存Node类型的其他对象。但出于某种原因,当我打印出这个基本上只返回nodes.size()的叶节点的> get_nr_children时,我得到完全随机(负)整数,它应该实际返回0.更有趣的部分:每次编译和执行时,它都会输出不同的整数,这些整数总是一些低负数。我不知道发生了什么!

Node.h

#include <string>
#include <vector>

using namespace std;

class Node
{
public:
    virtual ~Node();
    Node(string name = "");
    string get_name() const;
    void set_name(string& new_name);
    int get_nr_children() const;
    Node* get_child(int i) const;
    void add_child(Node child);
    void create_complete_tree(int nr_child_nodes, int tree_depth);
    void print();

private:
    string name;
    static int node_id;
    vector<Node> nodes = {};
};

Node.cpp

#include "node.h"
#include <sstream>

using namespace std;

Node::Node(string name) {
    node_id++;
    nodes = {};
    if (name == "") {
        stringstream str_sm;
        str_sm << (node_id);
        string node_id_str = str_sm.str();
        this->name = "node_" + node_id_str;
    } else {
        this->name = name;
    }
}

Node::~Node() {
    nodes.clear();
    // node_id = 0;
}

int Node::node_id = 0;

string Node::get_name() const {
    return name;
}

void Node::set_name(string& new_name) {
    this->name = new_name;
}


int Node::get_nr_children() const {
    return nodes.size();
}

Node* Node::get_child(int i) const {
    if (i >= nodes.size()) {
        return NULL;
    }
    Node node = nodes[i];
    Node *ptrNode = &node;
    return ptrNode;
}

void Node::add_child(Node child) {
    nodes.push_back(child);
}

void Node::create_complete_tree(int nr_child_nodes, int tree_depth) {
    tree_depth--;
    if (tree_depth <= 0) {
        return;
    }
    for (int i = 0; i < nr_child_nodes; i++) {
        Node* node = new Node();
        this->add_child(*node);
        node->create_complete_tree(nr_child_nodes, tree_depth);
    }
}

void Node::print() {
    cout << this->get_name() << "\n";
    cout << "I got this many children " << this->get_nr_children();
    for (int i = 0; i < this->get_nr_children(); i++) {
        cout << "\t";
        this->get_child(i)->print();
        cout << "\n";
    }
}

的main.cpp

#include <iostream>
#include "node.cpp"

using namespace std;

    int main() {
        Node* root = new Node("root");
        Node* left_child = new Node("left child");
        Node* right_child = new Node("right child");

        root->add_child(*left_child);
        root->add_child(*right_child);

        root->print();

        return 0;
    }

当我执行它时,我得到:

  我得到了这么多孩子2孩子我得到了这么多孩子   -62802357正确的孩子我有这么多孩子-62802357

     

处理完成,退出代码为0

3 个答案:

答案 0 :(得分:3)

Node* Node::get_child(int i) const {
    if (i >= nodes.size()) {
        return NULL;
    }
    Node node = nodes[i];
    Node *ptrNode = &node;
    return ptrNode;
}

Node node返回后,返回指向已销毁的本地get_child(i)的指针。下面是正确的代码,它返回一个指向矢量中子项的指针。

Node* Node::get_child(int i) const {
    if (i >= nodes.size()) {
        return NULL;
    }
    return &nodes[i];
}

main可以在没有指针和内存泄漏的情况下更轻松地实现。

int main() {
    Node root("root");

    root.add_child(Node("left child"));
    root.add_child(Node("right child"));

    root.print();

    return 0;
}

答案 1 :(得分:3)

您的问题源于

this->get_child(i)->print();

get_child返回指向本地对象的指针。当函数返回时,该对象被销毁,因此对返回print的{​​{1}}的调用正在处理已被销毁的Node

您需要做的是将指针直接返回到向量元素,如

Node

答案 2 :(得分:1)

问题在于函数Node* Node::get_child(int i) const。它返回一个指向对象的指针,该对象在函数调用结束时被销毁。

Node* Node::get_child(int i) const {
    if (i >= nodes.size()) {
        return NULL;
    }
    Node node = nodes[i]; // <- node is a copy of nodes[i]
    Node *ptrNode = &node;
    return ptrNode;       // <- returns a pointer to node
}                         // <- local objects are destroyed, including node

您必须从向量返回指向实际元素的指针。

Node* Node::get_child(int i) const {
    if (i >= nodes.size()) {
        return NULL;
    }
    return  &nodes[i]; // <- Returns the address of the actual node
}