Are there any legit websites to go to for help?

Pages: 12
I knew it! When I run the debugger, the "tree" never changes. Well, sh*t. I should start over I guess, so I can figure out what I'm doing. The problem (or part of it, anyway) is that he gives us the code, but he tends to make mistakes here and there that are SO HARD to debug. So I don't really know how to start over...isn't this fun?
So, what AM I doing? Nothing? Lol. Just reading in words and then printing them out? Is this even a linked list, perhaps? Because that's my other problem area.

oh, and here is the updated one, btw. I added the spaces when I fixed the 0. Now the whole thing does print out, but what does that mean?

Program:
http://pastebin.com/embed_iframe.php?i=hJeePiDy

Here's the output:
http://pastebin.com/embed_iframe.php?i=gV1TYfYf"

Last edited on
To modify main's root, you need to pass a reference to root (&root). This means a little re-work of all of your code (so insert accepts a tNode** and knows how to use it).

Forget about that though, we don't need main to have a root.

The first thing to understand is that you have two objects, a node and a tree. A node holds the data, and left/right pointers, and the tree is the way these nodes are organized.

These are two different classes. The basic set-up would be:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
typedef string tType;

class tNode
{
  // For this I just keep these public.
public:
  tType value;
  tNode* left;
  tNode* right;

  // Classes can have constructors, so this saves some code later
  tNode(tType v)
  {
    value = v;
    left = NULL;
    right = NULL;
  }

  // This is a destructor, it's called automattically when the class
  // goes out of scope.  Don't call it yourself. 
  ~tNode(void)
  {
    // We don't have to do anything
  }
};

class tTree
{
private:
  tNode* root;  //  The tree's root node.  Note that it is a pointer

  // This function destroys the tree.  It will be recursive
  void destroy(tNode* current);


public:

  // Construct
  tTree(void)
  {
    root = NULL;  // very important
  }
  // Destruct
  ~tTree(void)
  {
    //destroy(root); uncomment when we create destroy
  }

  // Public access to the destroy function.  Main has no idea
  // about root, so there are no arguments
  void clear(void);
};


Have you learned about header files? If so, that would be the next thing to know about. Otherwise, we can now do this:
1
2
3
4
5
int main(void)
{
  tTree myTree;
  return 0;
}


One thing that your code is missing is all of the deletes that are needed when you make new. This is called a memory leak, and it is bad.

tTree makes new when a node is created, and then edeletes all of the nodes in the destructor.

To really show this, we need an insert and print method. Note that tNode is untouched (and will remain untouched... until it gets the "count" variable).
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#include <iomanip>  // among other things

class tTree
{
private:
  tNode* root;  //  The tree's root node.  Note that it is a pointer

  // This function destroys the tree.  It will be recursive
  void destroy(tNode* current)
  {
    delete current;  // It is okay to delete a NULL pointer, but not a garbage one
  }
  
public:

  // Construct
  tTree(void)
  {
    root = NULL;  // very important
  }
  // Destruct
  ~tTree(void)
  {
    destroy(root);
  }

  // Public access to the destroy function.  Main has no idea
  // about root, so there are no arguments
  void clear(void){
    destroy(root);
    root = NULL;
  }
  
  void print(void)
  {
    cout << "Address: " << setw(8)  << root
       << " Value: "  << setw(12) << left << root->value
       << " Left: "   << setw(8)  << root->left
       << " Right: "  << setw(8)  << root->right
       << endl;
  }
  
  void insert(tType newValue)
  {
    root = new tNode(newValue);
  }
  
};

int main(void)
{
  tTree myTree;
  myTree.insert("Hello");
  myTree.print();
  return 0;
}


Granted, It's not very useful. This is the general structure of the tree though. If you found this helpful I can go further.

Edit:: I'm actually having some trouble getting this to work at all without a tNode**, we'll see.
Last edited on
Thank you, and yes, it is very helpful to see it all together. The teacher only shows us things in chunks, and then we have to put it all together, which obviously I'm not doing right.

Have you learned about header files? 


Yes, and no. I know they exist, I just have not been able to make one myself yet. It's on my list though, so I don't have to re-write all the same functions that I use in every assignment...Is that what you meant? I may be getting those confused with something else..

One thing that your code is missing is all of the deletes that are needed when you make new. This is called a memory leak, and it is bad.


Never heard of it. :(

So, yes, teach on! Please.
It's on my list though, so I don't have to re-write all the same functions that I use in every assignment...Is that what you meant? I may be getting those confused with something else..


You're right. Another bonus is that if you don't modify the .h, you wont have to re-compile it.

The general rule is that a .h shouldn't allocate memory (I believe). Functions that are very simple can go in a .h (int getNum(void) { return num; }, but I like to just throw them in the .cpp

We should make a .h asap.

So, the .h has the function/class definitions and other #include's that the class may need. It also has a few other pre-processor directives (# ) that make sure it is only loaded into your project once. The .cpp has all of the function bodies.

For example:

myPrint.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#ifndef MYPRINT_H    // If the file hasn't been loaded (basically)
#define MYPRINT_H  //  Load the file.

// Includes

#include <iostream>
//  using namespace std; would go here
//  But it isn't good practice to use an entire namespace in a header


// Function definitions

void print(int number);

#endif // To end the if statement in line 1 


Then we need a .cpp

myPrint.cpp
1
2
3
4
5
6
7
#include "myPrint.h"  // This looks for a myPrint.h in the same directory

// The function:
void print(int number)
{
  std::cout << "Your number is: " << number << std::endl; // std:: instead of "using namespace std;"
}


Finally main.cpp
1
2
3
4
5
6
7
8
#include "myPrint.h"

int main(void)
{
  for (int i = 0; i < 10; i++)
    print(i);
  return 0;
}


If myPrint.h, myPrint.cpp, and main.cpp are all in the same folder, you should have success with this.

Classes need something a little extra in the .cpp.



myPrint.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#ifndef MYPRINT_H    // If the file hasn't been loaded (basically)
#define MYPRINT_H  //  Load the file.

// Includes

#include <iostream>

// Class

class myIO
{
public:
  // Construct/Destruct
  myIO(void);  // The semi-colon promises this function will appear somewhere else
  ~myIO(void);   
 
 void print(int number);
}

#endif // To end the if statement in line 1 


myPrint.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include "myPrint.h"  // This looks for a myPrint.h in the same directory

// Class functions need "myIO::"

// Construct / Destruct
myIO::myIO(void)
{
  // Nothing
}
myIO::~myIO(void)
{
  // Nothing
}

void myIO::print(int number)
{
  std::cout << "Your number is: " << number << std::endl;
}


Finally main.cpp
1
2
3
4
5
6
7
8
9
#include "myPrint.h"

int main(void)
{
  myIO myInOut;
  for (int i = 0; i < 10; i++)
    myInOut.print(i);
  return 0;
}


See if you can get your tree using .h file like this. I would put the tNode and tTree in the same header.



Okay, will do. Thank you.
For the record, as far as legit sites go I don't think you'll find a better one that this.

The reference sections are clear and well written and there's a wealth of experience knocking around in the forums.

Someone will almost always know the answer to your query and, providing you show enough willingness to learn (which you clearly do, by the way), we'll always be willing to help out.
@ LowestOne: The pre-processor instruction #include literally inserts the code from the header file you designate to the location it was used in the object file. There's no "rule" about memory allocation or any of that stuff because it doesn't matter, it's the same thing as copying and pasting the code.
Topic archived. No new replies allowed.
Pages: 12