intersection function gets stuck after output - c++

void intersectionLists(LinkedList argList) {
bool common = false;
ListNode* thisCurrentPointer{headPointer};
ListNode* argCurrentPointer;
cout <<"common elements between both lists are:\n";
while(thisCurrentPointer != nullptr) {
argCurrentPointer = argList.getHeadReference();
while(argCurrentPointer != nullptr){
if(thisCurrentPointer->data == argCurrentPointer->data) {
cout <<thisCurrentPointer->data;
common = true;
break;
}
argCurrentPointer = argCurrentPointer->nextPointer;
}
thisCurrentPointer = thisCurrentPointer->nextPointer;
}
if(!common) {
cout <<"none\n";
}
thisCurrentPointer = nullptr;
argCurrentPointer = nullptr;
delete thisCurrentPointer;
delete argCurrentPointer;
}
Hello everyone,
Iwas making this function for intersection in the linkedList class, which has the parameter of another linkedList object, one utility function i am using on line 9 is getHeadReference(), which simply returns the address stored in the headPointer (i am using this function in order to get argCurrentPointer to point at the head of the list that came in the parameter).
Anyway.. the function gives perfectly fine output of whatever two linked lists are but the control get "stuck" right after its execution, the control freezes, and a huge garbage value is returned, i really hope i am being clear.
I have dry run the code i can not seem to find the problem. Even in main when i call another function after the execution of "intersectionLists" function, the called function gets executed properly without any delay but the control can't seem to exit main after all the work is done, when i don't call this intersection code, no hang or delay whatsoever is observed, please help. Thank you.

I think this is because you detele thisCurrentPointer and argCurrentPointer after setting them to null. It is not necessary to do any deletion after as you are not duplicating your nodes.

Related

Defining an object inside a function in a B+ tree

I am trying to implement a B+ tree. This is a very small portion of the actual code. I had some problems when passing an object pointer to a function. As far as I know, those objects created inside the function are destroyed afterwards. So what would be a good way to improve this without changing the semantics and still keep the function recursive. Any feedback would be appreciated.
void percolate_up(IndexNode* Current, int btree_order, IndexNode* Right, IndexNode* Root)
{
if(Current->Parent == NULL)
{
IndexNode* UpperNode = new IndexNode;
UpperNode->AddChild(Current);
UpperNode->AddChild(Right);
Current->Parent = UpperNode;
Right->Parent = UpperNode; //This is defined inside an if statement
// in main yet this statement doesn't affect it
UpperNode->AddKey(Current->Keys[btree_order]);
Root = UpperNode;
}
else if(.......){
...
...
percolate_up(....);
}
}
int main(){
...
if(...){
IndexNode* RightNode = new IndexNode;
percolate_up(Current, btree_order, RightNode, Root);
//RightNode->Parent is still NULL here but Current->Parent is changed
//Also Root is unchanged, Why does this happen?
}
All objects created with "new" will exists after function return. So you should use it.

reverse linked list using recursion

I am trying to reverse a linked list using recursion. I made the reverse() function to reverse the list. I created a linked list in main() and also defined print() method.
I don't know what mistake I am making. Please help me correct it. The code snippets are given below.
struct node
{
int data;
struct node *next;
}*head;
void reverse(node **firstnode,node *n)
{
if(n==NULL)
{
head=n;
return;
}
reverse(&head,n->next);
struct node *q=n->next;
n->next=q;
q->next=NULL;
}
void main()
{
......
head=first;
reverse(&first,first);
print(head);
}
It may not address your question directly. However, you mentioned C++11 in the tags. So, take look at std::forward_list. It is a standard container that is based on single linked-list.
List* recur_rlist(List* head)
{
List* result;
if(!(head && head->next))
return head;
result = recur_rlist(head->next);
head->next->next = head;
head->next = NULL;
return result;
}
void printList(List* head)
{
while(head != NULL) {
std::cout<<head->data<<" ";
head = head->next;
}
}
void main()
{
List* list = createNode(2);
append(list, createNode(3));
append(list, createNode(4));
append(list, createNode(5));
append(list, createNode(6));
List* revlist = recur_rlist(list);
printList(revlist);
}
I think you mixed up your addressing at the end of the reverse function, it should probably look like:
q->next=n;
n->next=NULL;
Also, I am not sure if you need the "firstnode" argument.
Since you want to understand the code, and you have several great resources with finished code already, more finished code examples aren't needed. I'll just answer with some concepts and point you at the errors you need to fix.
First, some background concepts.
Linked lists: first and rest
Any linked list is either empty, or can be broken down into first (a node) and rest (a smaller linked list, or empty). This makes recursion much easier.
if (head){
node * first = head;
node * rest = head->next;
}
Invariant (simplified): A guarantee that is always true at the start and end of your function.
In a linked list, you expect that head points to a node, which points to another node, and so forth, until you get to the end, which is signaled by a nullptr. All of the nodes are different. All of the nodes are valid. These are the guarantees that must be true before you call your function and when your function returns.
In a recursive function, the invariants must hold on the sublist you are reversing at every step, because you return from the function at every step. But this makes recursion much easier because all you have to do is make sure that if the input is good, then your function will return a good value at the current step.
End of recursion:
You can prove that your recursive function never gets in an infinite loop by combining the previous concepts. If the invariants hold, then each step will work, and because each recursive call will take rest, which is guaranteed to be either nullptr or a shorter list, eventually we have to reach the end. And of course show that you handle the end.
Okay, on to the actual problems:
You don't handle end of recursion correctly. You just set head=nullptr at the end, and I'm pretty sure that's not what you want for head. You may want to handle the end if (nullptr == n->next), because then you know that is the last node. Of course, you still have to correctly handle the trivial case where nullptr==head.
You don't preserve invariants. You tried, but it looks like your bookkeeping is just all wrong. I suggest using the debugger or 3x5 notecards to step through what you're actually doing to fix the actual work of swapping things around. For example, it looks like you just confused which node is which in this code snippet:
struct node *q=n->next; // n is first, q is rest
// what if nullptr == q?
n->next=q; // n->next = n->next doesn't actually change anything
q->next=NULL; // this must already be true if reverse(rest) did its job
// q and n were swapped?
Also, your function takes "firstnode" but does not use it, but instead sets the global variable "head" as a side effect.

My C++ program crashes on this function?

I'm a beginner programmer(Just started) and I'm writing some code for a binary search tree for fun.
For some reason, whenever I call this append function my program crashes. It has to do with one of the two functions itself, not anything else in the header file or my source file which includes main(). By the way Leaf is just a struct with an int value, and two Leaf pointers named left and right.
This crashes with no output error.
Leaf* BinarySearchTree::GetLeaf(int x,Leaf*a)
{
int key = a->value;
cout <<key<<"\n";
if(x > key)
{
if(a->right == NULL)
{
Leaf* newleaf = new Leaf();
newleaf->value = x;
a->right = newleaf;
return newleaf;
}
else if (a->right != NULL)
{
return a->right;
}
}
else if(x< key)
{
if(a->left == NULL)
{
Leaf* newleaf = new Leaf();
newleaf->value = x;
a->left = newleaf;
return newleaf;
}
else if (a->left != NULL)
{
return a->left;
}
}
else if(x == key)
{
//tbc
}
}
void BinarySearchTree::Append(int x)
{
if(root != NULL)
{
Leaf* current = root;
while(current->value != x)
{
current = BinarySearchTree::GetLeaf(x,current);
cout<<"value: "<<
current->value;
}
}
else
{
cout <<" No ROOT!";return;
}
}
If you want to see my main (source) file, go here(Since I don't want to flood this post)
http://pastebin.com/vrh7KkMm
If you want to see the rest of the header file, where these two functions are located,
http://pastebin.com/ZGWewPdV
In your BinarySearchTree constuctor, you start accessing root without having allocated memory for it first. This may be your crash. Try adding
root = new Leaf()
at the start of the constructor.
Edit - More information:
C++ does not automatically set values for your member variables, you normally need to initialize them by hand. (c++11 does allow you to do it in the declaration). This means that any variable that you don't set to a value will have a garbage value in it. If you use this garbage value as a pointer, you will most likely get a crash.
In your case, one of the initial problems is that the LinkedList class did not initialize its root member variable in the constructor before starting to reference it.
BinarySearchTree has the same problem.
Learning to use the debugger is one of the best things you can do when learning to program. It lets you step through your code one line at a time and look at the value of each variable. This makes i easy to see where things aren't going as you planned. Which debugger you use depends on your platform.
If GetLeaf() is called with x == key the function returns neither nullptr nor a valid pointer. This is a potential crash source. You need to return something sensible in any case.
UPDATE: Don't forget to initialize the Leaf structure properly in its constructor (all three members).
UPDATE2: Also initialize your root properly. I would initialize it with nullptr and change the append function in a way that it creates the very first leave if root==nullptr.

Queue class not dequeuing correctly

i asked a similar question here yesterday and i corrected some of the issues but the main one still persists.
Im enqueuing and dequeueing Position objects into a Position queue.As i enqueue 2 different Position objects, and dequeue both back out, both Position objects that are returned have the same value as the 2nd object put in. When i check the values that have been enqueued inside the enqueue function they are correct.I dont understand how this wont work as ive worked out the logic and used the dequeue algorithm verbatim from a book;
The Position class has 3 array based stacks as private members
struct Posnode
{
Position *pos;
Posnode *next;
};
class Position
{
private:
Posnode *front,*back,header; //front = back = &header;
Pegs A,B,C;
Position::Position(int num): A(num), B(num), C(num)
{
front = back = &header;
A.assignpeg(num);//assigning 1 to n to each Peg
B.assignpeg(num);
C.assignpeg(num);
}
#include "Pegs.h"
#include "Position.h"
int main ()
{
Position pos(4), intial(3),p,m,n;
intial.geta();//poping Peg A stack
pos.getc();//poping Peg c stack
p.enqueue(intial);
p.enqueue(pos);
p.dequeue(m);//position 'pos' is returned rather than intial
p.dequeue(n);//position 'pos' is returned
cin.get();
return 0;
}
void Position::dequeue(Position&)
{
Position p;
Posnode *ptr=front->next;//front points to an empty node wi
p = *ptr->pos;//assigning the position in ptr to p
front->next = ptr->next;
if (back == ptr) {//if im at the end of the queue
back = front;
}
delete ptr;
return ;
}
void Position::enqueue(Position n)
{
Posnode *ptr = new Posnode;
ptr-> pos = &n;//copying Position n calls Pegs operator =
back->next = ptr;//values that are enqueued check back ok
back = ptr;
return;
}
Pegs& Pegs::operator=(const Pegs & ori)//Pegs copy contructor
{
top=-1;
disks = ori.disks;
peg = new int[disks];
int element=0,g=-1,count=0;
while (count <= ori.top)//copying elements if there are any in ori
{
++count;
element=ori.peg[++g];
push(element);
}
return *this;
}
Sorry mate, but there are many problems with your code. Some of them seem to be copy/paste errors, but other show lack of C++ understanding. I'll focus on the latter first.
The member function void Position::enqueue(Position n) copies all passed arguments by value. So what happens when you call it? The parameter is copied and inside the function you are dealing with this copy that will be disposed when the function's scope ends. So assignemtn ptr-> pos = &n will assign an address of a temporary object to pos. Data at the address of disposed object may still be valid for some time, as long as nothing writes over it, but you should never ever depend on this behaviour. What you should do is you should pass the parameter by reference, i.e. change the declaration to void Position::enqueue(Position& n). That way the actual object will be passed, not a automatic copy.
If you don't specify a name for an argument like in void Position::dequeue(Position&), you won't have access to it. Inside this function you create a local variable p and then assign the result to it. But because p is local it will be disposed when the function returns. Needless to say, the parameter that you pass to this function is inaccessible because it's unnamed. What you should do is you should declare the function like that: void Position::dequeue(Position& p).
As a good advice: you should do better job with isolating your case. For example, are Pegs connected in any way to the problems you are having? Also avoid declarations like Posnode *front,*back,header - in most cases they make code harder to read. And did you notice that your code has #includes inside class body?! You should never to that, except for times when you exactly know what you are doing. #include directives should be usually put in the first lines of a source file.

unintentional recursive call in destructor

I have created a class which includes a linked list and this class needs to have a destructor for deleting the linked list, which I have included however because the delete method itself calls the destructor I end up in an infinite recursive call situaction.
Here is the code:-
PolynomialNode::~PolynomialNode()
{
/*PolynomialNode* current_node_ptr = link;
PolynomialNode* header_ptr = link;
int index = 0;
if( link != NULL)
{
while( current_node_ptr != NULL)
{
index++;
current_node_ptr = current_node_ptr->get_link();
}
delete_nodes( &header_ptr, 0, index);
} */
PolynomialNode* current_node_ptr = link;
PolynomialNode* copy_ptr;
while( current_node_ptr != NULL)
{
copy_ptr = current_node_ptr->get_link();
current_node_ptr->set_link(NULL);
delete current_node_ptr;
current_node_ptr = copy_ptr;
}
}
Note I tried this with a recursive call - intentional for deleting the linked list and I still have the same problem.
Any help would be much appreciated.
NB: I know it's a recursive call because when I step through the debugger I can see it happening.
assuming link is the pointer to the next PolynomialNode, simply
PolynomialNode::~PolynomialNode()
{
delete link;
}
will do the right thing recursively.
However, a better solution might be to retain your while() loop but move it out of the node to the destructor of a separate class representing the linked list as a whole.
Add this line in the while loop, before delete:
if ( current_node_ptr == this ) continue;
This will allow you to avoid recursion, by skipping destruction of the node that is calling. However, you should ask yourself why the heck did this happen in the first place. I cannot answer that question, because I don't see the rest of the code.
Note: this is wrong unless you have a circular link, in case of which this would be a valid design, as long as you skip deleting this.
Assuming link is the pointer to the next PolynomialNode, simply
if(this->link != NULL) delete this->link;