From: Chris Koeritz Date: Sun, 3 Oct 2021 01:23:14 +0000 (-0400) Subject: problem was new, cleaner, smarter tree destructor X-Git-Tag: 2.140.128^2~5 X-Git-Url: https://feistymeow.org/gitweb/?a=commitdiff_plain;h=84fc634d86157509079210d5b103deaa2122f9b7;p=feisty_meow.git problem was new, cleaner, smarter tree destructor it seems like a good algorithm but is somehow causing double deletes, where the second delete sees a malconfigured object. not good. --- diff --git a/nucleus/library/nodes/symbol_tree.cpp b/nucleus/library/nodes/symbol_tree.cpp index bd985a27..eb8b64c1 100644 --- a/nucleus/library/nodes/symbol_tree.cpp +++ b/nucleus/library/nodes/symbol_tree.cpp @@ -19,12 +19,12 @@ #include #include -//#define DEBUG_SYMBOL_TREE +#define DEBUG_SYMBOL_TREE // uncomment for totally noisy version. #include #undef LOG -#define LOG(s) CLASS_EMERGENCY_LOG(program_wide_logger::get(), s) +#define LOG(s) CLASS_EMERGENCY_LOG(program_wide_logger::get(), astring(s) + a_sprintf(" [obj=%p]", this)) using namespace loggers; using namespace basis; @@ -40,7 +40,16 @@ public: symbol_tree_associations(int estimated_elements) : symbol_table(estimated_elements) {} virtual ~symbol_tree_associations() { + +//hmmm: below was really wrong and things are still wrong because we're letting the symtab destruct our trees? +// real thing would be to just toss any pointers referenced in the sym tab here. +// OR... not at all because sym tab stores objects, and expects objects, and since a pointer isn't an object it will not auto-delete? + + //hmmm: why was this here? was it ever needed? +//hmmm: maybe it's the missing link? + +//probably we don't actually want to whack here??? // for (int i = 0; i < symbols(); i++) { // WHACK(use(i)); // } @@ -59,10 +68,11 @@ symbol_tree::symbol_tree(const astring &node_name, int estimated_elements) symbol_tree::~symbol_tree() { FUNCDEF("destructor"); -LOG("prior to whacks"); +LOG("symtree dtor: prior to whacks"); WHACK(_associations); +LOG("symtree dtor: after whacking associations"); WHACK(_name); -LOG("after whacks"); +LOG("symtree dtor: after all whacks"); } int symbol_tree::children() const { return _associations->symbols(); } diff --git a/nucleus/library/nodes/tree.cpp b/nucleus/library/nodes/tree.cpp index 7398274b..38105f74 100644 --- a/nucleus/library/nodes/tree.cpp +++ b/nucleus/library/nodes/tree.cpp @@ -23,7 +23,8 @@ // uncomment if you want lots of debugging info. #undef LOG -#define LOG(s) CLASS_EMERGENCY_LOG(program_wide_logger::get(), s) +///#define LOG(s) CLASS_EMERGENCY_LOG(program_wide_logger::get(), s) +#define LOG(s) CLASS_EMERGENCY_LOG(program_wide_logger::get(), astring(s) + a_sprintf(" [obj=%p]", this)) using namespace basis; using namespace loggers; @@ -277,14 +278,16 @@ tree::tree() tree::~tree() { FUNCDEF("destructor"); +LOG("entry to tree destructor"); // must at least unhook ourselves from the parent so we don't become a lost // cousin. tree *my_parent = parent(); if (my_parent) my_parent->prune(this); my_parent = NULL_POINTER; // disavow since we are loose now. -#if 0 +#if 1 //hmmm: clean this code when it's been examined long enough. maybe already. +LOG("old code for tree destructor activating..."); //original version suffers from being too recursive on windoze, //which blows out the stack. linux never showed this problem. so, i @@ -298,6 +301,7 @@ tree::~tree() while (branches()) delete branch(0); // this relies on the child getting out of our branch list. #else +LOG("new code for tree destructor activating..."); // newer version of delete doesn't recurse; it just iterates instead, // which avoids the massive recursive depth of the original approach. @@ -313,10 +317,12 @@ tree::~tree() if (curr_node == NULL_POINTER) { // wayback has no children, so we can take action. +LOG("tree dtor: can take action on childless node..."); // if wayback is the same as "this", then we exit from iterations since // we've cleaned all the kids out. if (way_back == this) { +LOG("tree dtor: breaking out since at wayback node..."); break; } @@ -325,9 +331,12 @@ tree::~tree() // our remit, since wayback is not the same node as the top level one // in the destructor (as long as there are no cycles in the tree...). curr_node = way_back->parent(); // go up in tree on next iteration. +LOG("tree dtor: reset currnode, about to whack wayback..."); WHACK(way_back); // whack a node, finally. +LOG("tree dtor: after whacking wayback..."); } else { // okay, there's a node below here. we will spider down to it. +LOG("tree dtor: spidering to node below..."); continue; } } diff --git a/nucleus/library/tests_nodes/test_symbol_tree.cpp b/nucleus/library/tests_nodes/test_symbol_tree.cpp index fa4a5c8c..5ba5bd5f 100644 --- a/nucleus/library/tests_nodes/test_symbol_tree.cpp +++ b/nucleus/library/tests_nodes/test_symbol_tree.cpp @@ -44,7 +44,9 @@ using namespace unit_test; #define DEBUG_SYMBOL_TREE // how many nodes we add to the tree. -const int MAX_NODES_TESTED = 40000; +//const int MAX_NODES_TESTED = 40000; +//hmmm: TEMPORARY!!! +const int MAX_NODES_TESTED = 2; class test_symbol_tree : public unit_base, public application_shell {