1

I am experimenting with a linked list. My function "null" seems to modify my list even though the list is not passed by reference. I've read that these problems can occur with objects that are passed as normal call-by-value parameter and that it is one the reasons that data inside a class is not declared as an public member in good OOP. I have tried the null function as an member function of the list and it works fine, but I still would like to understand why this way doesn't work properly. Thanks

#include <iostream>
#include <new>
#include <time.h>
#include <stdlib.h>
using namespace std;

class list{
    public:
    struct element {
    int data;
    element* next;
};

element * head;


list(){
    head=NULL;
}

~list(){
while (head!=NULL){
    element *e = head->next;
    delete head;
    head = e;
    }
    cout<<"Destructing..\n";
}

void add (int value){
    element *e = new element;
    e->data = value;
    e->next = head;
    head= e;
    }
};

void fill10 (class list & l){
    for (int i= 0; i<10 ;i++){
    l.add((rand()%10)+1);
    }
}

bool null (class list l){
    if (l.head!=NULL){ return false;}
    return true;
}


int main ()
{
    srand(time(NULL));
    class list l;
    fill10(l);

    cout<<l.head->data<<endl;
    cout<<l.head<<endl;

    cout<<endl<<null(l)<<endl;//when I comment this everything works out as expected

    cout<<l.head->data<<endl; //this data is not the same anymore after null is called
    cout<<l.head<<endl;

   return 0;
}
rex123
  • 371
  • 3
  • 16

3 Answers3

2

The problem is the way you pass the parameter to the null function

bool null (class list l){
    if (l.head!=NULL){ return false;}
    return true;
}

When passing by value, you create a copy of your linked list. This copy will contain a copy of the same head pointer as the original.

When the function returns, the parameter will be destroyed, and its destructor deletes all the nodes which is shared between the original and the copy.

You either have to pass by reference, or define a copy constructor that creates new nodes for a copied list.

Bo Persson
  • 90,663
  • 31
  • 146
  • 203
0

Your null function takes a list by-value, but what's in the list? It's really just a pointer to the actual stuff (the element). So what ends up getting copied when you call-by-value is not the stuff (the element) but a pointer-to the stuff.

That's why it works, as you have it now.

John Dibling
  • 99,718
  • 31
  • 186
  • 324
0

When you pass l by value to null you invoke the copy constructor and head of the copy will point at the same head as l. When this copy goes out of scope at the end of null, head is deleted, which is the same head used by l.

There's something called the "rule of three" in C++ which states that whenever you define a destructor, copy constructor or assignment, you should define all of them.

Andreas Brinck
  • 51,293
  • 14
  • 84
  • 114