Thread: Pointers and References

  1. #1
    Registered User
    Join Date
    Jun 2006
    Posts
    5

    Pointers and References

    Is it possible to pass the address of a variable by reference? For example:

    Code:
    void function (int * & a)
    Is this legal?

  2. #2
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    When you pass by reference or by pointer, you pass in the address of the object, because that's what gets stored in the functions parameters.

    Compile this example if you need to see.
    Code:
    #include <iostream>
    
    void f (int &passed_in) {
       std::cout << "The address of the object in f() is " << &passed_in << "\n";
    }
    
    int main() {
       int n = 42;
       std::cout << "The address of the object in main() is " << &n << "\n";
       f(n);
       return 0;
    }
    Last edited by whiteflags; 06-15-2006 at 10:28 PM.

  3. #3
    Registered User
    Join Date
    May 2006
    Posts
    903
    Well, in fact, when you pass by pointer, you are passing the address of an object but when you pass by reference, you are passing a reference to an object which is nearly the same as the object itself.

  4. #4
    Lurking whiteflags's Avatar
    Join Date
    Apr 2006
    Location
    United States
    Posts
    9,612
    Meh.

  5. #5

  6. #6
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    To answer the original question, passing a reference to a pointer is legal. However, passing a pointer to a reference is illegal, as is passing a reference to a reference.

  7. #7
    Registered User
    Join Date
    Apr 2006
    Posts
    2,149
    It is legal, but it creates overhead.

    A reference is treated like a pointer internally. So when a referenced variable is accessed, a pointer is dereferenced. This is usually less system intensive than copying the value over, but with objects as small as pointers, the oposite is true.
    It is too clear and so it is hard to see.
    A dunce once searched for fire with a lighted lantern.
    Had he known what fire was,
    He could have cooked his rice much sooner.

  8. #8
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    Well, yeah, it creates overhead, but it also gives additional capability. A function of the form
    Code:
    void function (int * & a)
    is able to change the value of the pointer, a, passed and that change is visible to the caller. For example;
    Code:
    void function(int * &a)
    {
          delete a;
          a = new int;
    }
    
    int main()
    {
        int *x = new int;
        function(x);
        *x = 5;
    }
    then function() released the memory initially allocated. But, if we change the function of the argument is passed by value, viz.
    Code:
    void function(int * a)
    {
          delete a;
          a = new int;
    }
    then the main() function above yields undefined behaviour (as the change of the argument, a, in this version is not visible to main() but the original memory has been deleted). Additionally (even if we ignore that) the memory allocated within function() is leaked.

  9. #9
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    It is legal. But what does it yield?

    Code:
    int value = 26;        //ignore this one for now
    
    int raw = 13;
    int *ptr_raw = &raw;
    int* &ref_ptr_raw = ptr_raw;
    
    cout << "raw: " << raw << endl;
    cout << "*ptr_raw " << ptr_raw << endl;
    cout << "ref_ptr_raw " << ref_ptr_raw << endl;
    cout << "&ref_ptr_raw " << &ref_ptr_raw << endl;
    As you can see a reference to a pointer (ref_ptr_raw) yields the address of the pointer. It behaves exactly like a normal reference. In other words, it is just an alias of your pointer. You can use it to change your pointer...

    Code:
    int value = 26;   //Now using this one
    
    int raw = 13;
    int *ptr_raw = &raw;
    int* &ref_ptr_raw = ptr_raw;
    
    cout << "raw: " << raw << endl;
    cout << "*ptr_raw " << ptr_raw << endl;
    cout << "ref_ptr_raw " << ref_ptr_raw << endl;
    cout << "&ref_ptr_raw " << &ref_ptr_raw << endl;
    
    ref_ptr_raw = &value;
    cout << "\nChanged: ref_ptr_raw = &value" << endl;
    cout << "ref_ptr_raw " << ref_ptr_raw << endl;
    cout << "&ref_ptr_raw " << &ref_ptr_raw << endl;
    Notice how the syntax for the reference assignment is just the same as it is for pointers. That is because you can conceptually just look at your reference to a pointer as just another name for your pointer.
    Let's change back. But this time we change the pointer directly. And not the reference...

    Code:
    int value = 26;
    
    int raw = 13;
    int *ptr_raw = &raw;
    int* &ref_ptr_raw = ptr_raw;
    
    cout << "raw: " << raw << endl;
    cout << "*ptr_raw " << ptr_raw << endl;
    cout << "ref_ptr_raw " << ref_ptr_raw << endl;
    cout << "&ref_ptr_raw " << &ref_ptr_raw << endl;
    
    ref_ptr_raw = &value;
    cout << "\nChanged: ref_ptr_raw = &value" << endl;
    cout << "ref_ptr_raw " << ref_ptr_raw << endl;
    cout << "&ref_ptr_raw " << &ref_ptr_raw << endl;
    
    ptr_raw = &raw;
    cout << "\nChanged: ptr_raw = &raw" << endl;
    cout << "ref_ptr_raw " << ref_ptr_raw << endl;
    cout << "&ref_ptr_raw " << &ref_ptr_raw << endl;
    See how the pointer now points back to raw and the reference "followed"? You now have the same output as in the beginning.

    A reference to a pointer can be (and is) used. Some care though must be given to special cases like the one grumpy mentioned.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  10. #10
    Registered User
    Join Date
    Jun 2006
    Posts
    5
    Thanks guys! You've helped me a lot. I was in doubt about this 'cause all I've ever learned about references never mentioned functions like that... Thank you!

    But...

    Houston, I got a problem.
    I'm trying to implement a conversion from a Generic Tree to a Binary Tree...
    Code:
    void GenericNodeToBinaryNode (GenericTreeNode * gennode, BinaryTreeNode * & binnode)
    {
    // big algorithm
    
    BinaryTreeNode * GenericTreeToBinaryTree (GenericTreeNode * node)
    {
    	BinaryTreeNode * BinNode = NULL;
    	GenericNodeToBinaryNode (node, BinNode);
    	return BinNode;
    }
    I'm getting this error:

    Code:
    error C2668: 'GenericNodeToBinaryNode' : ambiguous call to overloaded function
    Can you help me? (I didn't write the algorithm 'cause I think it's unnecessary, if you need me to, I'll post it later)

  11. #11
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    I really suggest you get used to put the pointer operand either immediatly after the type or just before the object name. It makes for more readable code. As you have it, it's confusing. It looks like you are multiplying instead of declaring a pointer.

    int* ptr = &obj;
    or
    int *ptr = &obj;
    Both forms are more common. However, int * ptr = & obj while valid, is confusing. But even more so when defining functions like the one above.

    As a side note if you decide to stick to int* ptr, do not declare more than one pointer per line. Personally I prefer this form because it makes it more visible that I am declaring a pointer to int. However,

    int* ptr, ptr2;

    ptr2 is not a pointer to int, even though one might be lead to believe so at first glance. It is instead an int. The correct would have been int* ptr, *ptr2;. But this is slightly confusing too. Best option is to declare one pointer per line. Or use the other form...

    int* ptr;
    int* ptr2;

    or

    int *ptr, *ptr2;
    As for your question, this call here GenericNodeToBinaryNode (node, BinNode); is ambiguous. The arguments you are passing didn't allow the compiler to choose exactly which of the versions of GenericNodeToBinaryNode() it should use. Check your arguments types and the function definitions.
    Originally Posted by brewbuck:
    Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

  12. #12
    Registered User
    Join Date
    Jun 2006
    Posts
    5
    But it has only one definit... wait... OK, I got it. This implementation is a group work I'm making with some friends, and I'm keeping the prototypes at the beginning of the .cpp, so we only need to send one file to each other and it still makes it easy to, after it's all done, split the file into a .cpp and a .h. What happened is, I forgot to change the prototype... I feel so dumb now...
    Last edited by Hetcenus; 06-16-2006 at 09:31 AM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Passing Pointers or References?
    By leeor_net in forum C++ Programming
    Replies: 24
    Last Post: 02-04-2009, 02:29 PM
  2. Pointers and references?!? Help!
    By alyeska in forum C++ Programming
    Replies: 3
    Last Post: 10-30-2008, 10:23 AM
  3. Pointers v References
    By m37h0d in forum C++ Programming
    Replies: 28
    Last Post: 06-30-2008, 01:29 PM
  4. pointers
    By InvariantLoop in forum C Programming
    Replies: 13
    Last Post: 02-04-2005, 09:32 AM
  5. Pointers and references...
    By SushiFugu in forum C++ Programming
    Replies: 6
    Last Post: 12-08-2001, 04:21 PM