向量 returns 负大小 c++
Vector returns negative size c++
作为练习,我想打印出一个基于 Node 对象的树数据结构。这意味着,每个对象都有一个矢量节点,它再次包含其他节点类型的对象。但是出于某种原因,当我打印出基本上只是 returns nodes.size() 的叶节点的 this->get_nr_children 时,我得到了完全随机的(负)整数实际上 return 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;
}
当我执行它时,我得到:
root I got this many children 2 left child I got this many children
-62802357 right child I got this many children -62802357
Process finished with exit code 0
问题出在函数 Node* Node::get_child(int i) const
上。它 return 是一个指向在函数调用结束时销毁的对象的指针。
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
您必须 return 指向向量中实际元素的指针。
Node* Node::get_child(int i) const {
if (i >= nodes.size()) {
return NULL;
}
return &nodes[i]; // <- Returns the address of the actual node
}
Node* Node::get_child(int i) const {
if (i >= nodes.size()) {
return NULL;
}
Node node = nodes[i];
Node *ptrNode = &node;
return ptrNode;
}
在您上方 return 指向在 get_child(i)
returned 之后销毁的本地 Node node
的指针。正确的代码如下,return 是指向向量中子项的指针。
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;
}
你的问题源于
this->get_child(i)->print();
get_child
returns 指向本地对象的指针。当函数 returns 时该对象被销毁,因此在那个 returned Node
上对 print
的调用正在与一个已经被销毁的 Node
.
你需要做的是return直接指向向量元素的指针,如
Node* Node::get_child(int i) /*const*/ { // cant be const for the return
if (i >= nodes.size()) {
return NULL;
}
return &nodes[i];
}
作为练习,我想打印出一个基于 Node 对象的树数据结构。这意味着,每个对象都有一个矢量节点,它再次包含其他节点类型的对象。但是出于某种原因,当我打印出基本上只是 returns nodes.size() 的叶节点的 this->get_nr_children 时,我得到了完全随机的(负)整数实际上 return 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;
}
当我执行它时,我得到:
root I got this many children 2 left child I got this many children -62802357 right child I got this many children -62802357
Process finished with exit code 0
问题出在函数 Node* Node::get_child(int i) const
上。它 return 是一个指向在函数调用结束时销毁的对象的指针。
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
您必须 return 指向向量中实际元素的指针。
Node* Node::get_child(int i) const {
if (i >= nodes.size()) {
return NULL;
}
return &nodes[i]; // <- Returns the address of the actual node
}
Node* Node::get_child(int i) const {
if (i >= nodes.size()) {
return NULL;
}
Node node = nodes[i];
Node *ptrNode = &node;
return ptrNode;
}
在您上方 return 指向在 get_child(i)
returned 之后销毁的本地 Node node
的指针。正确的代码如下,return 是指向向量中子项的指针。
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;
}
你的问题源于
this->get_child(i)->print();
get_child
returns 指向本地对象的指针。当函数 returns 时该对象被销毁,因此在那个 returned Node
上对 print
的调用正在与一个已经被销毁的 Node
.
你需要做的是return直接指向向量元素的指针,如
Node* Node::get_child(int i) /*const*/ { // cant be const for the return
if (i >= nodes.size()) {
return NULL;
}
return &nodes[i];
}