how to stop void function from stack overflow - c++

Since void doesn't return anything, I don't know how to get a proper base case for a void function like the one I am trying to get.
struct TreeNode {
char value;
TreeNode *sibling;
TreeNode *child;
};
void serialize(std::ostream &out, TreeNode *root)
{
// If the root is nullptr, print "None"
if (root == nullptr)
out << "None" << "\n";
// Write out root's value
out << root->value << "\n";
// if there is no child
// write out "False"
// else
// write out "True"
// recursively call serialize on that child
if (root->child == nullptr)
out << false << "\n";
else
{
out << true << "\n";
serialize(out, root->child);
}
// recursively call serialize on the sibling
serialize(out, root->sibling);
}
Would it help if I rewrite serialize as a TreeNode type function instead, what would be my base case if I did that?
Note: this is one function from a project to create a tree-node data structure in c++.

In this code you are trying to call the serialize function recursively, but there is no termination condition specified. therefore as a result of which each time the recursive function-call the stack memory is occupied, eventually leading to stack overflow. Add the termination point like the return statement, it should work fine.
if (root == nullptr)
out << "None" << "\n";
return;

Related

How do I check if the program cout is empty?

I am facing a problem where I have a void function which prints out AVL tree node values using inorder traversal. However, I also need to print out "EMPTY" if the void function does not have any cout. And since the void function is recursive so I assume the cout << "EMPTY" << endl; can not be inside the function (Actually I tried but a lot of unncessary EMPTY were produced).My question is that is there any way I can check the program/function cout, something like: if(cout is empty){ print "EMPTY" }
void inorder(node* n){
if(n != NULL){
inorder(n->left);
cout << n->value << ' ';
inorder(n->right);
}
}
You can't query cout to find out whether it printed something or not. There actually is a method (tellp()) that returns the position of a std::basic_ostream stream (which is what cout is), but when called on cout is always returns -1, presumably because cout is not keeping track of the number of characters it has printed (aka its "position" within the output stream).
Therefore the only practical way to know if something was printed is to instrument your inorder() function to provide that information to the caller, via a return-value (as Retired Ninja suggests in the comments) or via some other mechanism (e.g. writing to a by-reference argument, or setting a global variable, or etc)
When you call inorder, it is guaranteed to produce some ouput if, and only if, its parameter is not NULL. So you can do this:
void inorderTraverse(node* n)
{
if (n == NULL)
std::cout << "EMPTY" << std::endl;
else
inorder(n);
}
Then, wherever you first call inorder, call inorderTraverse instead.
The way to do this is to have two functions:
one that the user calls, and which will print “EMPTY” if the tree is empty
one that does everything else
The common way to do this is with a “detail” namespace, but any other method for having a helper function would work as well:
namespace detail{
void inorder(node* n){
if(n != NULL){
inorder(n->left);
std::cout << n->value << ' ';
inorder(n->right);
}
}
}
void inorder(node* n){
if(n) detail::inorder(n);
else std::cout << "EMPTY";
}
Another common way of doing this is having an additional, defaulted-argument (boolean, in this case) to indicate whether or not it is a toplevel invocation:
void inorder(node* n, bool is_top=true){
if (n != NULL){
inorder(n->left, false);
std::cout << n->value << ' ';
inorder(n->right, false);
}else if(is_top){
std::cout << "EMPTY";
}
}
I personally do not like flaggy code, though — the helper function is an old, recognizable idiom and avoids the overhead of the boolean tests at every leaf node.

Trying to write my own linked list impementation in c++, code segfaults after hitting 3 elements in the list

I've been trying to write my own implementation of linked list, but the code segfaults when I try to access an the third element or anything after it. Adding elements doesn't segfault, but accessing does. I can't find the pointer error in my get() function.
Each node in the list stores data (of Template t) and a pointer leading to the next node. I have two functions for everything- one for the first element, and one for any subsequent elements. The get() function for the subsequent elements always segfaults. I have some debug messages in the function that spit out results I can't explain. For example, if I run a get() request for the second element, an then the third, the code doesn't segfault, but it does return clearly incorrect results. Debug messages I placed indicate the segfault occurs when the second element calls the function to check the third element, if it occurs at all. Try the code with and without the line cout << newList.get(2) << endl; and you'll get very different results.
One possible cause is the pointer storage- I have the get() function output the pointer of each element (except the first) as it cycles through, and compare them to the pointers outputted by the add() function, and and pointers for element 0 and 1 match, but 2 and beyond do not match, and I can't seem to figure out why that would be.
#include <iostream>
using namespace std;
template <class T> class myLinkedList{
T data;
myLinkedList<T> *next = NULL;
public:
myLinkedList(T input){
data = input;
}
void add(T input){
if(next == NULL){
myLinkedList<T> newItem(input);
next = &newItem;
cout << "adding to list, data is " << input << ", pointer is " << next << endl;
}else{
myLinkedList<T> nextEntry = *next;
nextEntry.add(input);
}
}
T getData(){
return data;
}
//the start of the get function, only used by the first entry in the list
T get(int entry){
int currentPosition = 0;
if(entry == currentPosition){
return getData();
}else{
//defrefrence the pointer anc check the next entry
myLinkedList<T> nextEntry = *next;
return nextEntry.get(entry, ++currentPosition);
}
}
private:
//this vesion is the hidden, private vesion only used by nodes other than the first one
//used to keep track of position in the list
T get(int entry, int currentPosition){
//cout << currentPosition << endl;
if(entry == currentPosition){
return data;
}else{
//derefrence the pointer and check the next entry
cout << next << endl;
myLinkedList<T> nextEntry = *next;
currentPosition++;
T output = nextEntry.get(entry, currentPosition);
return output;
}
}
};
int main(){
myLinkedList<int> newList(3);
newList.add(4);
newList.add(5);
newList.add(7);
newList.add(9);
cout << newList.get(2) << endl;
cout << newList.get(3) << endl;
return 0;
}
Results are clearly erroneous- program should spit oout two macthing sets of pointers, as well as the numbers 5 and 7 ( the list elements)
One of your main problems is here:
if(next == NULL){
myLinkedList<T> newItem(input); // <<<<<<<<<<<<<
next = &newItem;
cout << "adding to list, data is " << input << ", pointer is " << next << endl;
}
you allocate an item on stack inside the if scope. Then you make next to point to this item. But... lifetime of the item is bounded by this scope. As son as you exit the scope, this item does not exist any longer. You need to allocate it dynamically by 'new' or other methods.
I had a breakthrough! Following Serge's solution was helpful, but one more change was needed- rather than create a function reference in the else block of my add function,
eg
myLinkedList<T> nextEntry = *next;
nextEntry.add(input)
i needed to use the pointer directly, as in
next->add(input)
I didn't know my pointer/object syntax

Why are my deque elements moving around?

I am implementing a simple Tree class to use in a parser, where I need to traverse the structure of the parse tree and build it up incrementally.
This is a stripped-down version of the class that demonstrates the issue (executable in this repl.it session):
template <typename T>
class Tree {
T val;
std::deque<Tree<T>> children;
public:
Tree() {}
Tree(T value) : val(value) {}
Tree(T value, std::deque<Tree<T>> children) : val(value), children(children) {}
std::deque<Tree<T>> getChildren() { return this->children; }
void appendChild(T value) {
this->children.push_back(value);
// this->children.emplace_back(value);
std::cout << "Appended child to node with value " << this->val << ".\n";
printChildren();
}
void printChildren() {
std::cout << "children for " << this << "(" << this->val << ")"
<< ": { ";
for (auto &child : this->children) {
std::cout << &child << "(" << child.val << ") ";
}
std::cout << "}\n";
}
};
For each node, the children are stored in a std::deque so children can be added to either end. In testing my class, I am finding that I cannot rely on the structure produced by building up the tree incrementally as opposed to all-at-once with an initializer list.
Here's some code to exercise the class and show what's happening:
std::cout << "Constructing Tree\n\n";
Tree<int> t(1);
t.appendChild(2);
t.getChildren()[0].appendChild(3);
std::cout << "\n\nPrinting tree from main\n\n";
t.printChildren();
t.getChildren()[0].printChildren();
This has the following output:
Constructing Tree
Appended child to node with value 1.
children for 0x7ffe9fd41820(1): { 0xb69080(2) }
Appended child to node with value 2.
children for 0xb694a0(2): { 0xb696b0(3) }
Printing tree from main
children for 0x7ffe9fd41820(1): { 0xb69080(2) }
children for 0xb698c0(2): { }
As you can see, the addresses of the node with the value 2 are different each time they are printed out. When it's first appended to the 1 node, it has the address 0xb69080. After it gets its own children, it has the address 0xb694a0. Then, when it's accessed from the main function, it has the address 0xb698c0.
Additionally, it seems that when it gets moved it somehow loses its children. The last line should show that the 2 node has a single child with value 3.
What's going on here?
I suppose your problem is here
std::deque<Tree<T>> getChildren() { return this->children; }
getChildren() return a copy of children.
Try with
std::deque<Tree<T>> & getChildren() { return this->children; }
// .................^
to return a reference to the internal children, if you want modify it using the returned value.
I mean: if getChildren() return a copy of children, with
t.getChildren()[0].appendChild(3);
you append a child with value 3 to the first element of the copy of children returned by getChildren().
This copy isn't saved so it's a temporary value that is destroyed immediately after, losing the 3 child appended.

why this function is not returning value expected

below is a searchVal function for searching a value in a binary tree. nodes of binary tree are stored in a vector nodeVec with first object in vector as root.
structure of nodes
class bst{
public:
//other functions..//
int searchVal(int)
private:
bst *lLink;
int info;
bst *rLink;
}
calling part in main
cout << "Enter Value to search ";
int val;
cin >> val;
int ret = nodeVec[0].searchVal(val);
if (ret == 2)
cout << "Value Not Found" << endl << endl;
else
cout << "Value Found" << endl << endl;
Function
int bst::searchVal(int val)
{
if (info != val)
{
if (info > val)
{
if (lLink != NULL)
lLink->searchVal(val);
else
return 2;
}
if (info < val)
{
if (rLink != NULL)
rLink->searchVal(val);
else
return 2;
}
}
if (info == val)
return 1;
}
while debugging (using codeBlocks) i observed that after any condition is met for example if the condition info==val is met the execution pointer (arrow in the IDE pointing to line being processed) goes to end of searchVal and after that it go to nearest if(from the end) however it does not go into the block of that condition. It always returns the info stored in root node in ret not 1 or 2
Should be
if(lLink!=NULL)
return lLink->searchVal(val);
^^^^^^
I think the major problem in your code is that you're not returning the result of the sub-tree searches; i.e. you should be doing this:
if(lLink!=NULL)
return lLink->searchVal(val);
You're missing the return keyword. That means that some execution paths go all the way through to the end of the function, and never hit a return, which is potentially very bad. The compiler should be issuing an error or warning about that though.
The searchVal function needs a return value on every code path - everything else has undefined behaviour (which means that anything could happen).
Add a return to your calls to lLink->searchVal and rLink->searchVal.
(And if your compiler didn't warn you about this, you need to enable that warning.)

How to fix logic errors in my binary search tree?

so I have been trying to get an old c++ binary search tree program of mine to work.It compiles and runs but I do not get the results I would expect. If I insert c,d,a,b in that order and try to remove c, my remove function skips the if conditionals that find in order successors. Why are those 2 else if conditionals skipped?
Also it is compiled using gcc.
Node::Node(string nodeItem,
int nodeLine){
item=nodeItem;
vector<int> tempVector;
tempVector.push_back(nodeLine);
lines=tempVector;
leftPtr = NULL;
rightPtr = NULL;
}
// recursive method for finding node containing the word
Node* BST::find(string data, Node *curr) {
if(curr==NULL) {
cout << data << " is not in the tree" << endl;
return curr;
}
if(curr->getItem().compare("theplaceholder")==0){
return curr;
}
string tempItem = curr->getItem();
//this if statement is if I am inserting a word that is already in the tree
// or if I am removing the word from the tree
if(data.compare(tempItem)==0){
return curr;
}
else if(data.compare(tempItem)<0){
return find(data,curr->getLeftPtr());
}
else{
return find(data, curr->getRightPtr());
}
}
void BST::insert(string data, int fromLine) {
Node *curr;
curr=find(data, root);
if(curr!=NULL && curr->getItem().compare("theplaceholder")==0){
curr->setData(data);
curr->addLines(fromLine);
}
if(curr==NULL){
// I want to point to a nonNull node.
// I am making a new node and having curr point to that instead of NULL
//then I set it to
curr=new Node(data, fromLine);
cout <<curr->getItem() << endl;
vector<int> foundLines=curr->getNodeLines();
//cout<< "The word " <<curr->getItem() << " can be found in lines ";
if(foundLines.empty())
cout << "foundLines is empty";
int size=foundLines.size();
for(int count=0; count<size; count++){
//cout << foundLines[count] << ", ";
}
}
if(curr->getItem()==data){
curr->addLines(fromLine);
}
}
// remove method I am trying to check for in order successors to swap with the deleted node.
void BST::remove(string data) {
Node *curr=root;
Node *temp=find(data, curr);
if(temp==NULL){
cout << " nothing to remove" << endl;
}
else if(temp->getRightPtr()!=NULL){
curr=temp->getRightPtr();
cout << curr->getItem() << endl;
while(curr->getLeftPtr()!=NULL){
curr=curr->getLeftPtr();
cout << curr->getItem() << endl;
}
temp->setData(curr->getItem());
temp->setLines(curr->getNodeLines());
delete curr;
curr=NULL;
}
else if(temp->getLeftPtr()!=NULL){
cout <<"if !temp->getLeftPtr" << endl;
curr=temp->getLeftPtr();
cout << curr->getItem() << endl;
while(curr->getRightPtr()!=NULL){
curr=curr->getRightPtr();
cout << curr->getItem() << endl;
}
temp->setData(curr->getItem());
temp->setLines(curr->getNodeLines());
delete curr;
curr=NULL;
}
else{
cout <<"else delete temp" << endl;
delete temp;
temp=NULL;
}
}
The reason this line
else if(temp->getRightPtr()!=NULL){
never succeeds is that you never set the right pointer on any node - getRightPtr can only return null. If you'd examined the state of your tree in the debugger after you'd built it or if you stepped through the insert function you'd probably have seen this. The problems are:
your find function doesn't return null if the node isn't in the tree, whereas your insert function expects it will
your insert function needs to locate the position in the tree where this node should be - either through fixing the find function or on its own, then create a new node AND add a reference to it from the parent node, on either the left or right side as appropriate
your insert function appears the line number to the first-inserted node twice: once when you overwrite the placeholder and once at the end of insert (rather than use a placeholder here I'd probably have initialised root to be null and instead set root = curr when you create the first node)
your remove function needs to do more work when promoting the highest node from the left-hand branch; it needs to
correctly clean up that node from it's previous parent - at the moment you delete the object but leave any dangling pointers alone
promote any children of that node before you move it to take its previous slot
i.e.
D C
/ \ / \
A E remove 'D' A E
\ => 'C' is highest on left \
C but need to move B to C B
/
B