Thread: Newbie question about pointers in function parameters.

  1. #1
    Registered User
    Join Date
    Jan 2007
    Posts
    4

    Newbie question about pointers in function parameters.

    Hi,

    I've read a lot of tutorials about pointers, However, I frequently see people use the & reference operator in a way that is not explained in any tutorials that I have read.

    This is the kind of thing that confuses me:

    Code:
    void trim(string& str)
    {
      string::size_type pos1 = str.find_first_not_of(' ');
      string::size_type pos2 = str.find_last_not_of(' ');
      str = str.substr(pos1 == string::npos ? 0 : pos1, 
        pos2 == string::npos ? str.length() - 1 : pos2 - pos1 + 1);
    }
    It expects me to just pass a normal string like this: trim(mystring);

    However, I don't really understand what is happening here, the function parameter seems to be asking for the address of a string, Although it will not accept this: trim(&mystring);

    The way that I personally would write such a function is like this:

    void trim(string* str)
    {

    }

    and I would pass the pointer like this: trim(&mystring);

    This makes sense to me, But I frequently see people using the & operator in function defintions, and I don't understand what it does.

  2. #2
    The superhaterodyne twomers's Avatar
    Join Date
    Dec 2005
    Location
    Ireland
    Posts
    2,273
    trim(mystring);

    will work. You want to understand why? You could use the * and & method, but it's 'easier' to use the & in the function.

  3. #3
    Registered User
    Join Date
    Dec 2006
    Posts
    69
    It's called a reference

  4. #4
    Registered User
    Join Date
    Jan 2007
    Posts
    4
    Thanks yeah, I really want to understand why it works, that particular function was just an example I found.

    It is my understanding that the whole point of using pointers is to avoid copying memory unnescessarily. So it feels odd to me that some functions like this ask me to pass a normal variable instead of a pointer.

    So are you saying that using "void trim(string& str)" is just an alternative to writing "void trim(string* str)... And that people use it because is saves you the effort of adding a & to the variable that you pass?

  5. #5
    Ethernal Noob
    Join Date
    Nov 2001
    Posts
    1,901
    Quote Originally Posted by sojurn
    It expects me to just pass a normal string like this: trim(mystring);

    However, I don't really understand what is happening here, the function parameter seems to be asking for the address of a string, Although it will not accept this: trim(&mystring);

    The way that I personally would write such a function is like this:
    Code:
    void trim(string* str)
    {
    
    }
    
    and I would pass the pointer like this: trim(&mystring);
    This makes sense to me, But I frequently see people using the & operator in function defintions, and I don't understand what it does.
    You're passing a reference to the string. By using the & operator it's telling the function that as far as it's concerned it's getting just the address of the actual object, so not to copy it entirely. It's the same as having a pointer as an object variable and passing the address only you reduce one syntax symbol, it's the same thing. trim(&mystring); won't work because the parameter is asking for an object, which it will take as a reference, so passing the address wouldn't work. Much like if you had a pointer as the parameter and just passed it the object. Sure it may be seen within function scope as a pointer, but you must pass it an address, since that is what a pointer stores.

    See this for why;
    Code:
    string a = "Hello";
    string &b = a;
    basically that makes a a string, and b a reference to a string. You don't pass it the address of a because it is a reference.

  6. #6
    The superhaterodyne twomers's Avatar
    Join Date
    Dec 2005
    Location
    Ireland
    Posts
    2,273
    It's just an alternative. Read C+/-'s link.

  7. #7
    Registered User
    Join Date
    Jan 2007
    Posts
    4
    Ah yes, that article explains it quite clearly, and it also mentions the confusion that it can cause and the recommendation to write it the other way :-)

    Thanks for the replies folks, and inparticular your lenghty one indigo. I really did read a lot of tutorials, I don't know why I never came across that article, when this site was the first I found when looking for a help forum.

    Thanks, it all makes sense now.

  8. #8
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    > It is my understanding that the whole point of using pointers is to avoid copying memory unnescessarily.

    Not the whole point. There's others reasons to choose a pointer; needing to alter the variable the pointer points to, from within the function, is one of them. Another is having a big object that we don't wish to waste resources making a copy of it. There are other possibilities too... like simply the object not allowing copies of itself.

    Also, passing a pointer may still "copy memory unnecessarily" if it is possible to pass a reference instead. A rule of thumb is use pointers when you must, references when you can. When passing a pointer to a function, the pointer object is copied. Keep in mind that a pointer is much like any other object, and unless you pass it by reference, it will spawn a copy when passed by value.
    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.

  9. #9
    Registered User
    Join Date
    Jan 2007
    Posts
    4
    Quote Originally Posted by Mario F.
    A rule of thumb is use pointers when you must, references when you can. When passing a pointer to a function, the pointer object is copied. Keep in mind that a pointer is much like any other object, and unless you pass it by reference, it will spawn a copy when passed by value.
    I'll bear that one in mind, I tend to use pointers as i'm used to working with windows API functions and they all work that way - which seemed to be perfectly in line with all the tutorials that I read on pointers. This other way of passing references threw me off.

  10. #10
    Ethernal Noob
    Join Date
    Nov 2001
    Posts
    1,901
    Also when you have an input/output stream as a parameter, it can't be copied, so you have to pass them by references.

  11. #11
    Registered User
    Join Date
    May 2003
    Posts
    1,619
    Quote Originally Posted by Mario F.
    Also, passing a pointer may still "copy memory unnecessarily" if it is possible to pass a reference instead.
    I'm not sure I see how. On virtually any compiler, both the pointer and reference have the same size; e.g. on a 32 bit compiler passing a pointer or passing a reference both involve pushing one 32-bit value onto the stack. In fact it's even the SAME 32 bit value, the address of the object.

    A pointer is like a primitive that just holds an address; so is a reference for that matter. Its size is the size needed to address into your program's memory space. In general passing a pointer won't be any different to the program than passing a reference.

    The only real difference is the syntax that the compiler allows you to use to access the object or data that is at that memory location. In general you should prefer references when doable because of the stricter requirements that the compiler enforces (like you can't explicitly create a NULL reference, etc.)

    In general you should prefer to pass parameters:

    Primitives, value should not be modified by function -- Pass directly (as a copy)
    Objects, not modified by function -- Pass as reference to const.
    Primitives, value needs to be modified -- Pass as reference
    Objects, value needs to be modified -- Pass as reference.

    A few examples where you would want to pass by pointer instead of reference:
    1. When the parameter can be EITHER an object or NULL.
    2. When the parameter is the memory address of a buffer your function should write into
    3. When the parameter is already a pointer in your calling function, often you should keep it as a pointer (or pointer-to-const).
    The reason is, with a pointer you can at least test if it's a NULL pointer. If you pass as a reference (e.g. func(*ptr) where func takes a reference), you can still have a NULL reference and you can't even test for it.
    4. Passing an array by pointer to the first element. (Though a reference to std::vector is much, much better!)
    Last edited by Cat; 01-20-2007 at 06:59 PM.
    You ever try a pink golf ball, Wally? Why, the wind shear on a pink ball alone can take the head clean off a 90 pound midget at 300 yards.

  12. #12
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    > I'm not sure I see how.

    A pointer being passed by value involves a copy of that pointer. I cannot alter the pointer itself (for instance, make it point to another address) unless I pass it by reference. Passing by value involves a copy operation.

    The address of a reference is the same address of the object being referred. If 32-bit compilers still create new instances of these objects, I fail to understand why aren't they addressable.

    EDIT:

    > both the pointer and reference have the same size

    This is new to me. sizeof of a reference to a user-defined class and a pointer to the same class, for instance, are significantly different on my machine.
    Last edited by Mario F.; 01-20-2007 at 08:35 PM.
    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.

  13. #13
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    sizeof of a reference to a user-defined class and a pointer to the same class, for instance, are significantly different on my machine.
    I think what Cat refers to is references being implemented as const pointers. sizeof of a reference would return the sizeof of the value/object itself, but what is actually passed around would be a const pointer in the guise of a reference.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  14. #14
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    Hmm... interesting. But is this really how it usually is implemented?
    It sure confuses me on a few details:

    - How is memory in the heap managed this way? Some references certainly can't be created in the stack if they are really const pointers under the hood...

    - Are then references just a language construct to simplify common pointer usage?

    - Why still keep the programmer away from the "true" address of a reference? I cannot come up with a reason of the top of my head...
    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.

  15. #15
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    But is this really how it usually is implemented?
    Not sure on that, but I remember reading that somewhere (probably in one of my C++ books).

    How is memory in the heap managed this way? Some references certainly can't be created in the stack if they are really const pointers under the hood
    Well, implemented that way, wouldnt they simply contain the address of something that already exists? Such addresses need only be placed on the stack, from what I understand.

    Are then references just a language construct to simplify common pointer usage?
    I suspect so, though references are more restrictive than pointers in general, which can be a Good Thing on occasion.

    Why still keep the programmer away from the "true" address of a reference?
    I think the benefit is that the programmer then thinks in terms of an alias, instead of thinking explicitly of a pointer.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Newbie function return question
    By faifas in forum C Programming
    Replies: 2
    Last Post: 06-29-2009, 10:19 AM
  2. Getting an error with OpenGL: collect2: ld returned 1 exit status
    By Lorgon Jortle in forum C++ Programming
    Replies: 6
    Last Post: 05-08-2009, 08:18 PM
  3. Staticly Bound Member Function Pointers
    By Polymorphic OOP in forum C++ Programming
    Replies: 29
    Last Post: 11-28-2002, 01:18 PM
  4. I need help with passing pointers in function calls
    By vien_mti in forum C Programming
    Replies: 3
    Last Post: 04-24-2002, 10:00 AM