Anil Gupta
Anil Gupta

Reputation: 29

Passing a pointer to a function

I was trying to implement BST using C++ , so i tried this:

    #include <iostream>
    #include <stdlib.h>
    struct node
    {
      int value;
      node* left;
      node* right;
    };

    void insert(node *cur , int val)
    {
      if(!cur)
      {
        cur = new node;
        cur->value = val;
        cur->left = NULL;
        cur->right = NULL;
        return;
      }

      if(val <= cur->value)
        insert(cur->left , val);
      else
        insert(cur->right , val);
    }

    using namespace std;

    int main()
    {
      node *root = NULL;


      insert(root , 20);
      insert(root , 21);

      cout<<(*root).value;

      return 0;
    }

but I have a problem, my insert() function works good, but the change in cur does not seem to reflect into the root pointer, as root remains NULL after the `insert() function calls. What is wrong here?

EDIT: Thanks for all your answers, making a pointer to a pointer seems to be to be ugly and tedious, is there any other way around, acheiving this with some other design?

Upvotes: 1

Views: 3583

Answers (5)

Galik
Galik

Reputation: 48605

If you want the function to operate on the outside pointer rather than a local copy you need to pass by reference:

void insert(node*& cur, int val)
{
    // ... 
}

Otherwise the function works on a copy of the pointer and the outside variable remains unchanged.

Upvotes: 1

st2rseeker
st2rseeker

Reputation: 483

If you reassign cur to a new node in insert, that does not mean that root is assigned that value (especially that root is not an address at all, but NULL).

Either pass a pointer to an empty node to insert on initialization (and update it with relevant data) or return a new node (and assign it to root in main).

Upvotes: 0

Sourav Ghosh
Sourav Ghosh

Reputation: 134286

Here, the root itself has been passed to insert() using pass-by-value. so, from insert(), the value of root cannot be changed. In other words, the cur is local to insert() function. Any changes made to cur itself won't impact the actual argument passed.

If you want to change the value of root from insert(), you need to pass a pointer to root from main().

To elabotare, you can change the value at the address pointed by cur from insert(). So, following the same analogy, if you change

  1. insert(&root , 20);
  2. void insert(node **cur , int val)
  3. all the occurrences of cur to *cur

you should be all good to go.

Upvotes: 1

Nidhoegger
Nidhoegger

Reputation: 5232

C++ makes function calls as Call by Value. So it makes a copy of the pointer and passes that to the function. If you pass that pointer, you have access to the data the pointer is pointing to, but NOT to the pointer outside the function itself, as only the adress the pointer is pointing to is copied.

You need to pass a pointer to the pointer if you want to modify the pointer itself (that would be the C attempt) or pass by reference, of which c++ is capable of.

If you want to use the C attempt:

void insert(node ** cur , int val)
if(!(*cur))
{
    (*cur) = new node;
    (*cur)->value = val;
    (*cur)->left = NULL;
    (*cur)->right = NULL;
    return;
}

or the C++ attempt (here you only have to modify the type of cur, everthing else will remain as it is):

void insert(node *& cur , int val)

Upvotes: 0

marom
marom

Reputation: 5230

The wrong is that you pas a pointer by value, change that value but the caller does not know about it. Change it to

void insert(node **cur , int val)
{
if(!*cur)
{
    *cur = new node;
    (*cur)->value = val;
    (*cur)->left = NULL;
    (*cur)->right = NULL;
    return;
}

if(val <= (*cur)->value)
    insert((*cur)->left , val);
else
    insert((*cur)->right , val);
}

And change function call accordingly (...exercise!)

Upvotes: 0

Related Questions