我的代码遇到了node = 0xddddddddd问题。我相信我已经将它缩小到三个规则的问题而没有复制构造函数。我确实尝试创建一个复制构造函数,但我不确定我是否正确实现它。本质上,我正在创建节点,将它们存储在二叉树对象中,我将其存储在向量中。我是否需要一直创建一个复制构造函数?
Environment.cpp
void Environment::evolve() {
std::cout << "> evolving function" << std::endl;
std::vector<Tree> popvec;
// Generate initial pop trees and store in vector
std::cout << "> generating initial population" << std::endl;
for (int i = 0; i <= Popsize-1; i++) {
Tree membertree(Maxdepth);
//popvec.push_back(membertree);
popvec.emplace_back(membertree);
} // <- A deconstructor is being called here that is causing the error
// If I understand right it is destructing the copy from putting it
// into the vector
Tree.cpp
// Constructor
Tree::Tree() {
root = NULL;
fitness = rand();
depth = 0;
}
// Overload constructor
Tree::Tree(int maxdepth) {
root = NULL;
fitness = rand();
depth = 0;
while (TreeDepth(root) < maxdepth) {
addNode(root);
}
}
// Copy constructor
Tree::Tree(const Tree &obj, int maxdepth) {
root = NULL;
fitness = obj.fitness;
depth = 0;
while (TreeDepth(root) < maxdepth) {
addNode(root);
}
}
// Destructor
Tree::~Tree() {
freeNode(root);
root = NULL;
}
// Post traversal node deletion
void Tree::freeNode(Node* node) {
if (node != NULL) {
freeNode(node->left); // This is where the error pops up
freeNode(node->right);
delete node;
}
}
// Adds a node to the tree
void Tree::addNode(Node* node) {
if (root == NULL) {
Node* temp = new Node();
root = temp;
}
else if (node->left == NULL) {
Node* temp = new Node();
node->left = temp;
}
else if (node->right == NULL) {
Node* temp = new Node();
node->right = temp;
}
else if (node->left != NULL) {
addNode(node->left);
}
else if (node->right != NULL) {
addNode(node->right);
}
}
编辑:有人要求树深度
int Tree::TreeDepth(Node* node) {
if (node == NULL) {
return 0;
}
int nLeft = TreeDepth(node->left);
int nRight = TreeDepth(node->right);
return (nLeft > nRight) ? (nLeft + 1) : (nRight + 1);
}
Node.cpp
Node::Node() {
functiontype = 0;
left = NULL;
right = NULL;
up = NULL;
}
// Do I need a copy constructor here as well?
Node::~Node() {
}
编辑:我似乎已经对此有所了解但是现在它似乎在尝试随机化向量时进一步失误
// Copy constructor
Tree::Tree(const Tree& obj) {
fitness = obj.fitness;
depth = obj.depth;
if(obj.root == NULL){
root = NULL;
}
else {
copyTree(this->root, obj.root);
}
}
void Tree::copyTree(Node * thisRoot, Node * sourceRoot) {
if (sourceRoot == NULL)
{
thisRoot = NULL;
}
else
{
thisRoot = new Node;
thisRoot->left = sourceRoot->left;
thisRoot->right = sourceRoot->right;
copyTree(thisRoot->left, sourceRoot->left);
copyTree(thisRoot->right, sourceRoot->right);
}
}
答案 0 :(得分:0)
如果您使用:
popvec.emplace_back(Maxdepth);
而不是:
popvec.emplace_back(membertree);
然后,不应该调用复制构造函数。试着这样做。
修改强>
我没有太多时间,抱歉。
复制构造函数的正确函数签名为:
Tree::Tree(const Tree &obj)
实际上,你标记为复制构造函数的东西可能甚至都没有被调用。
您能提供TreeDepth
所做的代码吗?
如果还有其他问题,请告诉我。
修改强>
我之前提供的功能没有用,我没有彻底检查,抱歉。
我测试了你的程序,我可以填充Tree
s的向量。我所做的是将copyTree
更改为:
void Tree::copyTree(Node *& thisRoot, Node * sourceRoot)
{
if (sourceRoot == nullptr)
{
thisRoot = nullptr;
}
else
{
thisRoot = new Node;
thisRoot->left = sourceRoot->left;
thisRoot->right = sourceRoot->right;
copyTree(thisRoot->left, sourceRoot->left);
copyTree(thisRoot->right, sourceRoot->right);
}
}
我所做的只是将thisRoot
参数更改为Node*&
。以前,更改thisRoot
并未更改root
,它只使指针本地指针指向新创建的节点。
我不知道fitness
或depth
做了什么,但目前它们似乎毫无用处。