Advertisement
If you have a new account but are having problems posting or verifying your account, please email us on hello@boards.ie for help. Thanks :)
Hello all! Please ensure that you are posting a new thread or question in the appropriate forum. The Feedback forum is overwhelmed with questions that are having to be moved elsewhere. If you need help to verify your account contact hello@boards.ie
Hi there,
There is an issue with role permissions that is being worked on at the moment.
If you are having trouble with access or permissions on regional forums please post here to get access: https://www.boards.ie/discussion/2058365403/you-do-not-have-permission-for-that#latest

C++ pointers

  • 09-03-2011 11:06pm
    #1
    Closed Accounts Posts: 6,556 ✭✭✭


    Hi,
    Just looking over an old project i did over 10 years ago in college on pointers in c++,
    I have this in a function declaration:
    void node::read_in(string k, node*&p)
    

    the node*&p is confusing me here, doesn't make much sense
    using it like this does it ? doesn't the * and the & cancel each other out in this case?
    doesn't the * dereference the & ?
    so wouldn't :
    void node::read_in(string k, node p)
    
    be the same ?


Comments

  • Registered Users, Registered Users 2 Posts: 40,038 ✭✭✭✭Sparks


    You're thinking C but writing C++ (ie. you're writing C++-- :D )
    node*&p is a pointer to a reference.


  • Registered Users, Registered Users 2 Posts: 5,246 ✭✭✭conor.hogan.2


    Im doing a little bit of c++-- myself :o


  • Closed Accounts Posts: 6,556 ✭✭✭the_monkey


    Thanks but I don't understand,
    void node::read_in(string k, node* p)
    
    This means p is a pointer to a type node, correct ?

    void node::read_in(string k, node*&p)
    

    So wouldn't this mean address of p is a pointer to a type node - which doesn't make any sense to me ?? .

    Or does it just mean pointer p is passed by reference ? but pointer types
    are always passed by reference :confused:


  • Registered Users, Registered Users 2 Posts: 40,038 ✭✭✭✭Sparks


    the_monkey wrote: »
    void node::read_in(string k, node* p)
    
    This means p is a pointer to a type node, correct ?
    Yup.
    void node::read_in(string k, node*&p)
    
    So wouldn't this mean address of p is a pointer to a type node
    Nope.

    Means that p is a reference to a pointer to a node object (sorry, got that round the wrong way in my last post, long day :o )
    A pointer is not a reference in C++. Similar, but not the same.

    This explains it in more detail, but basicly, if you pass in a reference to a pointer into your function, and you then mess with that parameter within the function (telling it to point elsewhere, for example), it only messes with the pointer within your function's scope. That's handy as it means that your function can't muck things up for other functions.

    eg. you have a reference to a pointer p and you pass that into read_in(). Through a typo that causes a wierd runtime error, read_in() sets that pointer p to NULL. If you'd passed in a straight pointer, you'd now get failures - quite possibly in other functions that depend on that pointer value (and gdb help you if it's a multithreaded application). But since you passed in a reference to a pointer, your wierd typo runtime bug only messes the pointer up in read_in()'s scope, and at worst, that localises the bug to just that function call in that thread and makes it easier to debug (at best, the error never hits anything else and you never see a crash).


  • Registered Users, Registered Users 2 Posts: 981 ✭✭✭fasty


    I've never seen code that actually would pass a reference to a pointer into a function in the wild even though in C++ land it's probably more correct.

    That said, C++ is best approached in a way that all features are optional! The defacto standard is to pass a pointer to a pointer when a function is going to allocate memory and make the pointer point to it. Likewise in C.
    void node::read_in(string k, node **p)
    


  • Advertisement
  • Registered Users, Registered Users 2 Posts: 40,038 ✭✭✭✭Sparks


    I've yet to encounter it in the wild as well, but it's taught because it's the safer way to do things. And in the wild, you learn quickly that coding standards that are safer but require more technical skill/time/effort get ignored quickly and replaced with quick hacks that build up cruft and technical debt :(

    That's one of the big problems with C++ - very few C++ coders in the real world actually code in C++. C++-- is endemic. Even in places where it really is C++ being coded, it's never all of C++, it's always a "safe subset" of C++ - see the Google coding rules for that (or the IBM ones or any big companys').


  • Registered Users, Registered Users 2 Posts: 3,323 ✭✭✭padraig_f


    Sparks wrote: »
    if you pass in a reference to a pointer into your function, and you then mess with that parameter within the function (telling it to point elsewhere, for example), it only messes with the pointer within your function's scope. That's handy as it means that your function can't muck things up for other functions.

    ^^^^^
    I think you have it the wrong way around.


    When you pass a plain pointer, e.g.
    void func( node* n );
    
    What you're passing in is a copy of the pointer value. This is fine if you're working on is the object that 'n' is pointing to: your local pointer and the one in the calling function both point to the same thing. The problem comes if you want to assign a new value to 'n' (typically allocate a new node).

    If, in your function, you now write:
    n = new node();
    
    Since you're only working on a copy of the original pointer, your local pointer and the one in the calling function now point to different things, which is not usually what you want (because the local variable will be unavailable when the function returns).

    To get around this, you pass in a reference to a pointer.
    void func( node*& n);
    
    Now if you allocate a new value to 'n' inside the function, since it's working on a reference and not a copy, the pointer in the calling function gets updated as well as the local one.

    So the reference is only necessary if you're assigning a new value to 'n'.

    An equivalent, but more common way of doing this is a pointer-to-pointer:
    void func(node **n);
    

    If you see a reference-to-pointer or pointer-to-pointer, the pointer is usually having a new object assigned to it inside the function.

    So this is why I think Sparks has it the wrong way around, a reference-to-pointer will also affect the pointer outside the function.


  • Registered Users, Registered Users 2 Posts: 40,038 ✭✭✭✭Sparks


    /looks

    /thinks a bit

    /goes away, does some coding

    :o

    Feck.
    Ahem.
    Yes, he's right.

    (This might be why Google demands that all parameters that are references must be declared const...)

    (I know this level of confusion is why I don't like C++ )


  • Registered Users, Registered Users 2 Posts: 981 ✭✭✭fasty


    Sparks wrote: »
    That's one of the big problems with C++ - very few C++ coders in the real world actually code in C++. C++-- is endemic. Even in places where it really is C++ being coded, it's never all of C++, it's always a "safe subset" of C++ - see the Google coding rules for that (or the IBM ones or any big companys').

    I think whenever you speak to someone about C++ as a language, they always like some bits and hate others but they're never the same bits!


  • Registered Users, Registered Users 2 Posts: 5,401 ✭✭✭DublinDilbert


    fasty wrote: »
    I've never seen code that actually would pass a reference to a pointer into a function in the wild even though in C++ land it's probably more correct.

    That said, C++ is best approached in a way that all features are optional! The defacto standard is to pass a pointer to a pointer when a function is going to allocate memory and make the pointer point to it. Likewise in C.
    void node::read_in(string k, node **p)
    
    Sparks wrote: »
    I've yet to encounter it in the wild as well, but it's taught because it's the safer way to do things. And in the wild, you learn quickly that coding standards that are safer but require more technical skill/time/effort get ignored quickly and replaced with quick hacks that build up cruft and technical debt :(

    That's one of the big problems with C++ - very few C++ coders in the real world actually code in C++. C++-- is endemic. Even in places where it really is C++ being coded, it's never all of C++, it's always a "safe subset" of C++ - see the Google coding rules for that (or the IBM ones or any big companys').

    Its very often used where there's large amounts of data being transferred, like in a network stack. I know the linux network stack passes in pointers to pointers.

    You could just pass in a pointer to where you want the data to be copied, but it would mean a "deep-copy" would need to be done on every byte of every packet coming in of the network to the location of the pointer. Instead they just modify the pointer passed in to point at the location of the new packet from the network and it doesn't need to be moved in memory.


  • Advertisement
  • Registered Users, Registered Users 2 Posts: 40,038 ✭✭✭✭Sparks


    That's pointers to pointers though DD, not references to pointers.
    And I'm not posting more on this till I've had coffee and have a compiler reference to hand, one embarressing whoopsie is enough for today :D


  • Registered Users, Registered Users 2 Posts: 3,945 ✭✭✭Anima


    Interesting, I never knew about that.

    Good thread!


  • Closed Accounts Posts: 6,556 ✭✭✭the_monkey


    Great stuff lads, learning loads, In college I skimmed over pointers didn't really like them and after 2nd year did mainly Java for this reason!


  • Registered Users, Registered Users 2 Posts: 1,481 ✭✭✭satchmo


    The right-to-left rule is a good way of avoiding confusion like this. Just read any combination of operators and keywords from right to left, and you'll understand what they are. For example:
    int * const * & foo;
    
    Foo is a reference to a pointer which points to a const pointer which points to an int. Simple really!


Advertisement