对于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
答案 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
}