Pass by value arguments changes orignal copy?

//This program calls unionLL function which takes list1 and list2 objects of //LinkedList type as arguments also nowhere in the function I had changed List1
//and List2 contents although the list1 and list2 head's and also their next //pointer remain same but the elem or data field is automatically updated to //some garbage value.


#include <iostream>

using namespace std;
typedef int E;

class LinkedList;

class Node
{
private:
E elem;
Node* next;
friend class LinkedList;
friend void unionLL(LinkedList list1,LinkedList list2, LinkedList& list3);
};

class LinkedList
{
private:
Node* head;
public:
LinkedList();
~LinkedList();
const Node* getHead();
bool empty() const;
bool find(const E e) const;
void display() const;
void addFront(const E e);
void removeFront();
};

LinkedList::LinkedList()
: head(NULL) {}

LinkedList::~LinkedList()
{
while(!empty())
removeFront();
}

const Node* LinkedList::getHead()
{
return head;
}

bool LinkedList::empty() const
{
return head == NULL;
}

bool LinkedList::find(const E e) const
{
Node* temp = head;
while(temp != NULL)
{
if(temp->elem == e)
return true;
temp = temp->next;
}
return false;
}

void LinkedList::display() const
{
Node* temp = head;
while(temp != NULL)
{
cout << temp->elem << "\t";
temp = temp->next;
}
cout << endl;
}

void LinkedList::addFront(const E e)
{
Node* nPtr = new Node;
nPtr->elem = e;
nPtr->next = head;
head = nPtr;
}

void LinkedList::removeFront()
{
Node* old = head;
head = old->next;
delete old;
}

void unionLL(LinkedList list1,LinkedList list2, LinkedList& list3)
{
cout << "List 1 head : " << list1.getHead() << endl;
cout << "List 2 head : " << list2.getHead() << endl;
Node* p_cur = (Node*)list1.getHead();
Node* q_cur = (Node*)list2.getHead();

while(p_cur != NULL)
{
int loc = p_cur->elem;
list3.addFront(loc);
p_cur = p_cur->next;
}

while(q_cur != NULL)
{
int loc = q_cur->elem;
if(list3.find(loc))
;
//Do Nothing
else
list3.addFront(loc);
q_cur = q_cur->next;
}
cout << "List 1 head : " << list1.getHead() << endl;
cout << "List 2 head : " << list2.getHead() << endl;

}


int main(int argc, char* argv[])
{
LinkedList list1;
LinkedList list2;
LinkedList unLinkedList;

list1.addFront(10);
list1.addFront(15);
list1.addFront(4);
list1.addFront(20);

list2.addFront(8);
list2.addFront(4);
list2.addFront(2);
list2.addFront(10);

cout << "List 1 : ";
list1.display();
cout << "List 2 : ";
list2.display();

unionLL(list1, list2, unLinkedList);
cout << "Union LinkedList : ";
unLinkedList.display();
cout << "Why List 1 and List 2 are changing after calling union function ? " << endl;
cout << "List 1 : ";
list1.display();
cout << "List 2 : ";
list2.display();
return 0;
}
Last edited on
1
2
3
4
5
6
7
8
9
class LinkedList
{
	private:
		Node* head;
	public:
	//...
};

void unionLL(LinkedList list1,LinkedList list2, LinkedList& list3);

When you call `unionLL()' a "copy" is created for the first and second argument
Then thing is how is that copy made.

Because you did not define a copy-constructor yourself the one that the compiler provides it used.
It would simply copy each member.

That means that both list have a `head' pointer that points to the same cell.
When the function ends, the local variables are destroyed, so list1.~List(); is invoked.

So after the function ends, you've got a list with a head that points to garbage.


So your problem is that you didn't follow the rule of three
"If you need to explicitly declare either the destructor, copy constructor or copy assignment operator yourself, you probably need to explicitly declare all three of them.|
Topic archived. No new replies allowed.