Note that there are some explanatory texts on larger screens.

plurals
  1. POglibc detected *** ./a.out: munmap_chunk(): invalid pointer:
    text
    copied!<p>There are many questions like this but after looking at some cases, I guess this question is case-specific so I post my code and pointed out where the problem takes place may you be patient reading my code?</p> <h3>uniBTree.h</h3> <pre><code>#ifndef uniBTree_H #define uniBTree_H #include "uniTreeNode.h" #include &lt;cassert&gt; template&lt;class T&gt; class uniBTree { private: uniTreeNode&lt;T&gt; *root; int delete_helper(uniTreeNode&lt;T&gt; *); uniTreeNode&lt;T&gt; *insert_helper(uniTreeNode&lt;T&gt; *, const T); void in_print_helper(const uniTreeNode&lt;T&gt; *) const; void pre_print_helper(const uniTreeNode&lt;T&gt; *) const; void post_print_helper(const uniTreeNode&lt;T&gt; *) const; public: uniBTree(void); uniBTree(uniTreeNode&lt;T&gt; *r); ~uniBTree(void); void insert(const T i); void in_print(void) const; void pre_print(void) const; void post_print(void) const; }; template&lt;class T&gt; uniBTree&lt;T&gt;::uniBTree(void) { root = NULL; } template&lt;class T&gt; uniBTree&lt;T&gt;::uniBTree(uniTreeNode&lt;T&gt; *r) { root = r; } template&lt;class T&gt; int uniBTree&lt;T&gt;::delete_helper(uniTreeNode&lt;T&gt; *n) { int count = 0; if (n == NULL) return 0; count += delete_helper(n-&gt;get_left()); count += delete_helper(n-&gt;get_right()); delete n; count++; return count; } template&lt;class T&gt; uniBTree&lt;T&gt;::~uniBTree(void) { int count = delete_helper(root); std::cout &lt;&lt; "uniBTree&lt;T&gt;::~uniBTree&lt;T&gt;(void)\n"; std::cout &lt;&lt; count &lt;&lt; " nodes deleted\n"; } template&lt;class T&gt; void uniBTree&lt;T&gt;::in_print() const { in_print_helper(root); } template&lt;class T&gt; void uniBTree&lt;T&gt;::pre_print() const { pre_print_helper(root); } template&lt;class T&gt; void uniBTree&lt;T&gt;::post_print() const { post_print_helper(root); } template&lt;class T&gt; void uniBTree&lt;T&gt;::in_print_helper(const uniTreeNode&lt;T&gt; *current) const { if (current == NULL) return; in_print_helper(current-&gt;get_left()); current-&gt;print(); in_print_helper(current-&gt;get_right()); } template&lt;class T&gt; void uniBTree&lt;T&gt;::pre_print_helper(const uniTreeNode&lt;T&gt; *current) const { if (current == NULL) return; current-&gt;print(); pre_print_helper(current-&gt;get_left()); pre_print_helper(current-&gt;get_right()); } template&lt;class T&gt; void uniBTree&lt;T&gt;::post_print_helper(const uniTreeNode&lt;T&gt; *current) const { if (current == NULL) return; post_print_helper(current-&gt;get_left()); post_print_helper(current-&gt;get_right()); current-&gt;print(); } template&lt;class T&gt; void uniBTree&lt;T&gt;::insert(const T i) { if (root == NULL) root = new uniTreeNode&lt;T&gt;(i, NULL, NULL); else insert_helper(root, i); } template&lt;class T&gt; uniTreeNode&lt;T&gt; *uniBTree&lt;T&gt;::insert_helper(uniTreeNode&lt;T&gt; *current, const T i) { if (current == NULL) {//this is will only dealed by attempting to visit leaves... //if root is null, it'll be handled in insert uniTreeNode&lt;T&gt; *child = new uniTreeNode&lt;T&gt;(i, NULL, NULL); assert(child != NULL); return(child); } if (i &lt; current-&gt;get_data()) current-&gt;set_left(insert_helper(current-&gt;get_left(), i)); else current-&gt;set_right(insert_helper(current-&gt;get_right(), i)); return(current); } #endif </code></pre> <h3>uniTreeNode.h</h3> <pre><code>#ifndef uniTreeNode_H//for redefinition #define uniTreeNode_H #include &lt;iostream&gt; //using namespace std; don't use using namespace xxx and include source file in .h file template&lt;typename T&gt; class uniTreeNode { private: T data; uniTreeNode&lt;T&gt; *left; uniTreeNode&lt;T&gt; *right; public: //uniTreeNode&lt;T&gt;(void); uniTreeNode(T d, uniTreeNode&lt;T&gt; *l, uniTreeNode&lt;T&gt; *r); T get_data(void) const; uniTreeNode&lt;T&gt; *get_left(void) const; uniTreeNode&lt;T&gt; *get_right(void) const; void set_left(uniTreeNode&lt;T&gt; *l); void set_right(uniTreeNode&lt;T&gt; *r); void print() const; }; template&lt;typename T&gt; uniTreeNode&lt;T&gt;::uniTreeNode/*remember syntax here*/ (T d , uniTreeNode&lt;T&gt; *l = NULL, uniTreeNode&lt;T&gt; *r = NULL) { data = d; left = l; right = r; } template&lt;typename T&gt; T uniTreeNode&lt;T&gt;::get_data(void) const { return data; } template&lt;typename T&gt; uniTreeNode&lt;T&gt; * uniTreeNode&lt;T&gt;::get_left(void) const { return left; } template&lt;typename T&gt; uniTreeNode&lt;T&gt; * uniTreeNode&lt;T&gt;::get_right(void) const { return right; } template&lt;typename T&gt; void uniTreeNode&lt;T&gt;::set_left(uniTreeNode&lt;T&gt; *l) { left = l; } template&lt;typename T&gt; void uniTreeNode&lt;T&gt;::set_right(uniTreeNode&lt;T&gt; *r) { right = r; } template&lt;typename T&gt; void uniTreeNode&lt;T&gt;::print() const { std::cout &lt;&lt; "data is " &lt;&lt; data &lt;&lt; std::endl; } #endif </code></pre> <h3>date.h</h3> <pre><code>#include &lt;ostream&gt; class date{ private: int y; int m; int d; public: date();//default constructor date(const long int);//used by cplr as convert constructor date(int, int , int); friend bool operator&lt;(const date &amp;d1, const date &amp;d2);//d1 is for left-hand date friend bool operator&gt;(const date &amp;d1, const date &amp;d2); bool operator==(date d); bool operator!=(date d); date &amp;operator=(date d); friend std::ostream &amp;operator&lt;&lt;(std::ostream &amp;out, date d); friend std::istream &amp;operator&gt;&gt;(std::istream &amp;in, date d); }; </code></pre> <h3>date.cc</h3> <pre><code>#include &lt;iostream&gt; #include &lt;cstdio&gt; #include &lt;time.h&gt; #include &lt;cstring&gt; #include "date.h" date::date(){ y = m = d = 0; } date::date(int Y, int M, int D){ y = Y; m = M; d = D; } date::date(const long int s){//#second since 1970/1/1 00:00:00 struct tm *buf; buf = gmtime(&amp;s); y = (buf-&gt;tm_year+1900); m = buf-&gt;tm_mon+1; d = buf-&gt;tm_mday; } bool operator&lt;(const date &amp;d1, const date &amp;d2){ bool result;//sizeof(bool) is 1 if(d1.y &lt; d2.y) result = true; else if(d1.y == d2.y){ if(d1.m &lt; d2.m) result = true; else if(d1.m == d2.m){ if(d1.d &lt; d2.d) result = true; else result = false; } else result = false; } else result = false; return result; } bool operator&gt;(const date &amp;d1, const date &amp;d2){ bool result;//sizeof(bool) is 1 if(d1.y &gt; d2.y) result = true; else if(d1.y == d2.y){ if(d1.m &gt; d2.m) result = true; else if(d1.m == d2.m){ if(d1.d &gt; d2.d) result = true; else result = false; } else result = false; } else result = false; return result; } bool date::operator==(date d){ return (this-&gt;y==d.y &amp;&amp; this-&gt;m==d.m &amp;&amp; this-&gt;d==d.d); } bool date::operator!=(date d){ return (this-&gt;y!=d.y || this-&gt;m!=d.m || this-&gt;d!=d.d); } date &amp;date::operator=(date d){ this-&gt;y = d.y; this-&gt;m = d.m; this-&gt;d = d.d; return *this; } std::ostream &amp;operator&lt;&lt;(std::ostream &amp;out, date d){ out &lt;&lt; d.y &lt;&lt; "/" &lt;&lt; d.m &lt;&lt; "/" &lt;&lt; d.d &lt;&lt; std::endl; return out; } std::istream &amp;operator&gt;&gt;(std::istream &amp;in, date d){ in &gt;&gt; d.y &gt;&gt; d.m &gt;&gt; d.d ; return in; } </code></pre> <h3>main function</h3> <pre><code>#include "uniBTree.h" #include "date.h" #include &lt;cstdio&gt; int main(){ date d1 = 100000000;//convert constructor uniTreeNode&lt;date&gt; node(d1, NULL, NULL); printf("%p %p\n", node.get_left(), node.get_right()); std::cout &lt;&lt; node.get_data() &lt;&lt; std::endl; date d2 = 86401; date d3 = 200000000; uniBTree&lt;date&gt; btree(&amp;node); return 0; } </code></pre> <p>I tested and found that its <code>&amp;node</code> that is invalid. I think it is because it tries to "release" <code>btree</code> at the end of the program and when the root is encountered, because it points to <code>node</code>, it can't perform good thing.</p> <p>I have two question:</p> <ol> <li>if construct a <code>node</code> like what I did,(<code>uniTreeNode&lt;date&gt; node(xxx, xxx, xxx);</code>) was the object "NEW"ed by the program?</li> <li>for the <code>uniTreeNode&lt;T&gt;</code> class template, I didn't write its destructor!! So, like what I say above, when node,which is pointed by root of <code>btree</code>, is to be released is there so-called "default destructor"? and is it called here ? And most importantly, is "DELETE" used by the program?</li> </ol> <p>If one of the two question above is no, is it why the problem arise?</p> <p>EDIT: now the problem is shown, but how can I adjust my code to fix this? any one any idea?</p> <p>EDIT: just modify like this:</p> <pre><code>uniTreeNode&lt;date&gt; *nodeptr = new uniTreeNode&lt;date&gt;(d1, NULL, NULL); </code></pre> <p>p.s. if not indirectly using a pointer to refer to our root of the btree(thus using new), new isn't used, and delete shouldn't be used; by this choice, delete_helper of uniTreenode should use this:</p> <pre><code>if(n != root){ delete n; count++; } </code></pre> <p>but this does not solve the problem... the ultimate question is:</p> <pre><code>"can we release object without using delete(because it isn't obtained from newing) in c++?" </code></pre> <p>REPLY:</p> <p>My "release"/"allocated" is actually saying about the memory, without specifying HOW it is done...but it's a big issue anyway</p> <p>You say "you can do that but it is almost always the wrong answer";you mean that I should use DELETE but not directly call the destructor?(actually that doesn't seem proper at all) -->please justify here</p> <p>Btw, for those instance NEWed by me, is it necessary for them to be DELETED by a statement if I want to release them? or they'll also be dealt like those automatic variable instance?(back when out of scope, by compiler) -->please correct the above if needed</p> <p>another Q: isn't there ANY existing statement I can use to do things, like what DELETE does, for those automatic instance? or, I can only call destructor, if I wish?</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload