Ram space exhausted while creating a Binary Search Tree of 60000 elements - c++

I am trying to build a huge binary search tree:
class Node
{
public:
int value;
shared_ptr<Node> left;
Node* right;
Node(int v):value(v){}
void addLeft(){
static int i;
shared_ptr<Node> node=make_shared<Node>(i);
left=node;
cout<<i++<<endl;
if(i<60000)
node->addLeft();
}
};
int main(){
shared_ptr<Node>root=make_shared<Node>(9);
root->addLeft();
return 0;
}
I get a seg fault over running this code, in valgrind I have this report:
==17373== Stack overflow in thread #1: can't grow stack to 0xffe801000
Any clue on how to build the BST without overflowing the RAM space?
Any help is much appreciated

Exceeding the stack is not the same as exceeding your RAM. Function calls accumulate on the stack, the problem is you are trying to place 60000 function calls and variables on the stack. Convert your function to a loop and you will be fine. It will even get rid of that terrible static int i.
Here is a version of your function using a for loop with no recursion.
void addLeft()
{
left = std::make_shared<Node>(0);
// tail is the last element to have been added to the tree
std::shared_ptr<Node> tail = left;
std::cout << 0 << std::endl;
// Add nodes from 1 to 60000 inclusively
for (int i = 1; i <= 60000; ++i)
{
std::cout << i << std::endl;
tail->left = std::make_shared<Node>(i);
tail = tail->left;
}
}

Related

Counting total of even in a BST

I'm trying to count total of leaves that have even numbers in a BST.
Example: root--> 2 4 6 8 9
Output: 4 leaf that have even numbers.
Here is what I have done:
struct BSTNode
{
BSTNode* left;
BSTNode* right;
int data;
};
int CountingTotalEven(BST* root)
{
int count = 0;
count++;
CountingTotalEven(BST* root);
return count;
}
My program output wrong number, I don't know what I'm doing wrong.
int count = 0;
count++;
CountingTotalEven(BST* root);
return count;
There are three main issues in this code currently. Firstly, you're initializing count in your recursive function as a non-static variable. So what happens is count gets initialized as 0 every time this recursive function is called.
Secondly, you've called the recursive function on the root again. What you want to do is call the function recursively for its right and left subtrees(read: Tree Traversals).
Thirdly, you're not checking if the value is actually even.Change your function to
static int count = 0;
if(count%2 == 0)
count++;
CountingTotalEven(root->left);
CountingTotalEven(root->right);
return count;

C++ Binary Tree Implementation - Deleting Pointer Causes

I am working on a pretty basic binary tree implementation in C++, but I am currently having a problem that deleting a pointer to the root node crashes the program. In Dev-C++ debug mode the error returned is: "Program received signal SIGTRAP, Trace/breakpoint trap", but when I check with "info breakpoints", it says there are no breakpoints or watchpoints. I'm pretty confused about this and have been spending a lot of time checking if I have used and declared all the pointers correctly, any help would greatly be appreciated!
#include <iostream>
#include <vector>
using namespace std;
class Node {
public:
int key;
Node * left_child = NULL;
Node * right_child = NULL;
};
class Tree {
public:
int num_nodes;
vector<Node> nodes;
int read() {
cin >> num_nodes;
nodes.resize(num_nodes);
int input_key, input_left, input_right, root_node = 0;
for (int i = 0; i < num_nodes; i++) {
cin >> input_key >> input_left >> input_right;
if(input_key >= nodes.size()) {
nodes.resize(input_key+1);
}
if(i==0) {
root_node = input_key;
}
nodes[input_key].key = input_key;
if(input_left >= 0) {
nodes[input_key].left_child = &nodes[input_left];
}
if(input_right >= 0) {
nodes[input_key].right_child = &nodes[input_right];
}
}
return root_node;
}
};
int main() {
Tree t;
int root_index = 0;
root_index = t.read();
Node * root_ptr = new Node;
root_ptr = &(t.nodes[root_index]);
delete root_ptr; //when I take this line out, it works
}
Sample Input (no output expected):
3
4 2 5
2 -1 -1
2 -1 -1
Firstly, this line is useless:
Node * root_ptr = new Node;
You immediately reassign root_ptr to something else. So the line does nothing but allocate memory. You then assign root_ptr as follows:
&(t.nodes[root_index]);
The variable t you declared on the stack. You end up getting a pointer to a vector element, an element you never allocated yourself. If you did not allocate it yourself, you cannot delete it. Any allocation by the vector will be handled by the vector, and the vector itself is a stack-allocated, so you cannot delete it.
That is why the delete line crashes.
Additionally, you say it is a simple binary tree implementation, but it is not. You have a vector in there, and you have a strange way of assigning the tree elements, so you've created some kind of hybrid data structure.

Segmentation Error C++

I am fairly new to the C++ language and I am trying to write a recursive method to traverse a tree. I have a traverse method but there is one line of code that causes a segmentation fault. I have tested this by commenting and uncommenting the line, compiling and executing. I have researched why segmentation errors are caused and do not see why any of what I am doing is causing a problem with the memory. Can someone give me advice about what I am doing wrong?
map<int, Node> theNodes;
void initialize()
{
// first we read the data
while (inStream.hasNext())
{
string nextLine = inStream.nextLine();
Node newNode = Node(nextLine);
this->theNodes[newNode.getSequence()] = newNode;
}
}
Code for getDownLinks() and getSequence
vector<int> downLinks;
int sequence;
vector<int> Node::getDownLinks() const
{
return this->downLinks; //
}
int Node::getSequence() const
{
return this->sequence;
}
Traversal Class Code
int totalPayoff;
Node headNode;
int Traversal::traverse()
{
Node headNode = theNodes[0];
std::vector<int> downLinks = headNode.getDownLinks();
for(int i = 0; i < downLinks.size(); i++)
{
int a = 0;
Node currentNode = theNodes[downLinks[i]];
traverseInner(a, currentNode);
}
return this->totalPayoff;
}
Here is the traverseInner function
int Traversal::traverseInner(int& level, Node& node)
{
std::vector<int> nodeDownLinks = node.getDownLinks();
if(nodeDownLinks.size() == 0)
{
totalPayoff = totalPayoff + node.getPayoff();
return 0;
}
for(int i = 0; i < nodeDownLinks.size(); i++)
{
int a = 0;
Node currentNode = theNodes[nodeDownLinks[i]]; <-- This causes segmentation error.
traverseInner(a, currentNode);
}
return totalPayoff;
}
Any variables that are not declared here are declared in the header file. The code compiles fine.
I'd also like to mention that I have written this code in many different ways and through my observations have come to the conclusion that any variable that is trying to be accessed in the braces of a nested statement cannot be accessed by the memory. Even the int a variable that is declared right above the problem statement and even hard coded data which is supposed to be there such as nodeDownLinks. If I try to print out through standard output the size of the vector inside one of the nested statements, I also get a segmentation error.
Probably the value inside "nodeDownLinks[i]" it is not initialized, having a memory random value, then you are trying to access this position in the
"theNodes" array and gives to you the segmentation fault.
Please, be sure the values inside "nodeDownLinks" are initialized.
99% it crashes because theNodes has less size, then nodeDownLinks[i] contains index. So nodeDownLinks[i] contains wrong index, u'd better check it and print what goes wrong this way:
int a = 0;
int link = nodeDownLinks[i];
if (theNodes.size() <= link)
std::err << "Wrong link " << link << " in Node" << std::endl;
else
traverseInner(a, theNodes[link]);
It shouldnt crash and you can find wrong index in nodeDownLink easily!

Knights tour passing arrays to linked list and more

I am currently working on the knights tour project. My goal ultimately is to create this project using backtracking (by implementing stack) and Warnsdorff's heuristic. I am not allowed to use any libraries that has stack functions already created such as push and pop. I am also not allowed to resolve the problem using recursion. With that being said, I am pretty stuck right now and my next big milestone would be to solve the problem by only backtracking.
I am not going to sugar coat this at all, but right now my code is one big mess. I have pretty much created all the tools I need to make the program run, but now I just need to put all the pieces together.
The following is my code:
#include<iostream>
using namespace std;
class linkedList{
struct node
{
int data;
node *next;
};
node *top;
public:
linkedList()
{
top = NULL;
}
void push(int coordinates)
{
node *p = new node;
p -> data = coordinates;
p -> next = top;
top = p;
}
int pop()
{
node *temp = top;
top = temp -> next;
return temp -> data;
}
int display()
{
cout<<"\n"<< top -> data;
top = top-> next;
}
};
// Linked List ================================================
class Board{
public:
int next;
int status[8][8];
Board();
void print();
};
Board::Board(){
for(int i=0; i<8; i++){
for(int j=0; j<8; j++){
status[i][j] = -1;
}
}
}//constructor
void Board::print(){
for (int j=0; j<8; j++){
for(int i=0; i<8;i++){
cout << status[i][j] << " ";
}
cout << endl << endl;
}
}
//BOARD========================================================
class Knight {
private:
public:
int vertical[8] = {2,-2,1,-1,2,-2,1,-1}; // possible knight moves x coordinate
int horizontal[8] = {1,1,2,2,-1,-1,-2,-2}; // possible knight move y coordinate
int counter;
int currentPos[2];
Knight();
};
Knight::Knight(){
currentPos[0] = 7; // x-coordiante
currentPos[1] = 7; // y-coordinate
counter = 0;
}//constructor
/* Use this later
int Knight::changePos(int i,int j){
Knight::currentPos[0] = (Knight::currentPos[0] + i);
Knight::currentPos[1] = (Knight::currentPos[1] + j);
counter++;
return counter;
*/
int main(){
Board b;
Knight k;
b.status[k.currentPos[0]][k.currentPos[1]] = k.counter;
b.print();
linkedList obj;
int coordinates;
}
So my idea at this point is to do the following:
Create a loop that will change the current position of the knight using the horizontal and vertical array (the possible moves of the knight). Once the position has changed, the counter will increment and the -1 will be replaced with the current counter value. When the knight has been moved, the information of the new coordinates needs to be passed to the linked list using the push function I created. In order to do this, I need to figure out a way to pass an array (x,y) or multiple values to push. I will also need to create some bound checking which I am currently working on (make sure the knight doesn't move to a spot that he has been to and doesn't go off the board). Then finally if the knight does get stuck, I need to use the pop function I created to go back a step and try to continue with a different move.
I really really appreciate any help, corrections, places to start or other suggestions that are given! I am so stuck..
Let me get this straight. You're having difficulty implementing the Stack structure that allows you to undo moves.
C++ isn't really my forte but here's how I'd approach the Stack
Define a struct that stores the coords (and possibly backtracking info)
Update 'node' to store a pointer to an instance of your new struct.
Update the 'push()' definition to use it.
Update the 'pop()' definition to return it.
Profit...

Memory leak in trivial stack implementation

I'm decently experienced with Python and Java, but I recently decided to learn C++. I decided to make a quick integer stack implementation, but it has a massive memory leak that I can't understand. When I pop the node, it doesn't seem to be releasing the memory even though I explicitly delete the old node upon poping it. When I run it, it uses 150mb of memory, but doesn't release any of it after I empty the stack. I would appreciate any help since this is my first foray into a language without garbage collection. This was compiled with gcc 4.3 on 64-bit Kubuntu.
//a trivial linked list based stack of integers
#include <iostream>
using namespace std;
class Node
{
private:
int num;
Node * next;
public:
Node(int data, Node * next);
int getData();
Node * getNext();
};
Node::Node(int data, Node * next_node)
{
num = data;
next = next_node;
}
inline int Node::getData()
{
return num;
}
inline Node* Node::getNext()
{
return next;
}
class Stack
{
private:
unsigned long int n;
Node * top;
public:
Stack(int first);
Stack();
void push(int data);
int pop();
int peek();
unsigned long int getSize();
void print();
void empty();
};
Stack::Stack(int first)
{
Node first_top (first, NULL);
top = &first_top;
n = 1;
}
Stack::Stack()
{
top = NULL;
n = 0;
}
void Stack::push(int data)
{
Node* old_top = top;
Node* new_top = new Node(data,old_top);
top = new_top;
n++;
}
int Stack::pop()
{
Node* old_top = top;
int ret_num = old_top->getData();
top = old_top->getNext();
delete old_top;
n--;
return ret_num;
}
inline int Stack::peek()
{
return top->getData();
}
inline unsigned long int Stack::getSize()
{
return n;
}
void Stack::print()
{
Node* current = top;
cout << "Stack: [";
for(unsigned long int i = 0; i<n-1; i++)
{
cout << current->getData() << ", ";
current = current->getNext();
}
cout << current->getData() << "]" << endl;
}
void Stack::empty()
{
unsigned long int upper = n;
for(unsigned long int i = 0; i<upper; i++)
{
this->pop();
}
}
Stack createStackRange(int start, int end, int step = 1)
{
Stack stack = Stack();
for(int i = start; i <= end; i+=step)
{
stack.push(i);
}
return stack;
}
int main()
{
Stack s = createStackRange(0,5e6);
cout << s.peek() << endl;
sleep(1);
cout << "emptying" <<endl;
s.empty();
cout << "emptied" <<endl;
cout << "The size of the stack is " << s.getSize()<<endl;
cout << "waiting..." << endl;
sleep(10);
return 0;
}
How do you KNOW the memory isn't being released? The runtime library will manage allocations and may not release the memory back to the OS until the program terminates. If that's the case, the memory will be available for other allocations within your program during its execution.
However.... you seem to have other problems. My C++ is really rusty since I've been doing Java for 15 years, but in your Stack::Stack constructor you're allocating a Node instance on the system stack and then storing a reference to it in your "Stack". That Node instance goes out of scope when the constructor ends, leaving a dangling pointer.
Stack::Stack(int first)
{
Node first_top (first, NULL);
top = &first_top;
n = 1;
}
This is wrong , you cant assign address of a local object to class member( top ) , since local objects get destroyed when function returns.
Create a node on heap rather than stack , do something like this :
Stack::Stack(int first)
{
top = new Node(first, NULL);
n = 1;
}
And Make the concept of link list clear and use pen and paper if you can do so.
Your Stack::Push(int) operation seems buggy check it out what you have forget to do.
My suggestion is try to implement generic stack with the help of template ,so it will work for all data type .
When createStackRange() returns it'll return a copy of the Stack using the compiler-generated copy constructor which just makes a bitwise copy (i.e., it'll copy the pointer to the first node and the size.)
More seriously, you're missing the destructor for the Stack class. Ideally you'd have it walk the list and call delete on each Node. The Stack object created on the processor stack will automatically be cleaned up automatically when main() exits, but without a destructor, the nodes will still be allocated when the program ends. You probably want something like this for it:
Stack::~Stack()
{
while ( top )
{
Next *next = top->getNext();
delete top;
top = next;
}
}
The way to think of it is that the C++ compiler will automatically generate copy constructors and destructors for you, but they're normally shallow. If you need deep behavior you've got to do it implement it yourself somewhere.
After poring over the code, I couldn't find the leak so I compiled it and ran it in a debugger myself. I agree with Jim Garrision - I think you're seeing an artifact of the runtime rather than an actual leak, because I'm not seeing it on my side. The issues pointed out by NickLarsen and smith are both actual issues that you want to correct, but if you trace the code through, neither should actually be causing the problem you describe. The code smith singles out is never called in your example, and the code Nick singles out would cause other issues, but not the one you're seeing.
Creat a stub to test your code and user Memory Analysis tool like "Valgrind". This will find out memory leaks and corruptions for you.
check man-pages for more information.
Note that you should only roll your own stack for educational purposes. For any real code, you should use the stack implementation that comes with the C++ standard library...