problem was new, cleaner, smarter tree destructor
authorChris Koeritz <fred@gruntose.com>
Sun, 3 Oct 2021 01:23:14 +0000 (21:23 -0400)
committerChris Koeritz <fred@gruntose.com>
Sun, 3 Oct 2021 01:23:14 +0000 (21:23 -0400)
it seems like a good algorithm but is somehow causing double deletes, where the second delete sees a malconfigured object.  not good.

nucleus/library/nodes/symbol_tree.cpp
nucleus/library/nodes/tree.cpp
nucleus/library/tests_nodes/test_symbol_tree.cpp

index bd985a27a1c883f6790849ff8b2ab9c65b5c5a2b..eb8b64c145392812d6592d681ce89555ea56d8d8 100644 (file)
 #include <textual/parser_bits.h>
 #include <textual/string_manipulation.h>
 
-//#define DEBUG_SYMBOL_TREE
+#define DEBUG_SYMBOL_TREE
   // uncomment for totally noisy version.
 
 #include <loggers/program_wide_logger.h>
 #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<symbol_tree *>(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(); }
index 7398274bd6e101f324c88e146dad9d32bf095860..38105f74a60bdf43f6cbc5a600d3ff241fb466ff 100644 (file)
@@ -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;
     }
   }
index fa4a5c8cb40c198b7db12eb60b45a14a365629d8..5ba5bd5fa374cb15263376d353f16449a7ab8d7a 100644 (file)
@@ -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
 {