CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 1 of 1
  1. #1
    Join Date
    Oct 2002
    Location
    Timisoara, Romania
    Posts
    14,360

    C++ General: What are the different methods to pass parameters to functions?

    Q: How are parameters passed to functions?

    A: In C++ there are two ways: by value and by reference. Passing by value means that a copy of the object is made on the callee’s stack and altering the object means altering a local copy so the caller’s object is unchanged when the function returns. Passing by reference means that the address of the object is send (a reference holds an address but behaves like an object) so that the callee can directly alter the original object.



    Q: What about passing by pointer?

    A: There is no such thing; it is a misconception. A pointer is a memory address. You can pass a pointer to a function, but the pointer is passed by value. You can distinguish between the two this way: if the parameter has a trailing & then it is passed by reference, otherwise by value.



    Q: May I see some examples?

    A: Yes. I was about to show you some.

    In this first example an integer is passed by value to function foo(), which increments it. Because a copy is made the variable in main remains unchanged and the program’s output is 0 1 0.
    Code:
    void foo(int i)
    {
      i++;
      cout << i << endl;
    }
    
    int main()
    {
      int i = 0;
    
      cout << i << endl;
      foo(i);
      cout << i << endl;
      
      return 0;
    }
    Because passing by value requires a copy to be made, you can pass objects by value only if the type (class or struct) they instantiate provides a copy constructor, because that is the only way an object of type T can be constructor from another object of type T.

    In this second example an integer is passed to foo() by reference, which means that altering it will directly affect the object in main and the output is 0 1 1.
    Code:
    void foo(int &i)
    {
      i++;
      cout << i << endl;
    }
    
    int main()
    {
      int i = 0;
    
      cout << i << endl;
      foo(i);
      cout << i << endl;
      
      return 0;
    }
    On the other hand you can pass a pointer (address) to an integer to foo(). The pointer is passed by value (which means that if you change the pointer in foo() it won’t affect the address of the object in main) but having the address of the variable in main we can directly change it. The output is the same as in the second example, i.e. 0 1 1.
    Code:
    void foo(int *i)
    {
      (*i)++;
      cout << *i << endl;
    }
    
    int main()
    {
      int i = 0;
    
      cout << i << endl;
      foo(&i);
      cout << i << endl;
      
      return 0;
    }
    When a function takes a pointer as parameter, it is reasonable to believe that someone will pass a NULL pointer (from various reasons) so you may want to test it for such situation.

    What if you want to pass a pointer to a buffer to a function and want the function to (re)allocate memory for it and fill it with some data? Simply putting it like this:
    Code:
    // This code is WRONG
    void foo(unsigned char *buffer)
    {
      // delete the previous buffer
      if(buffer != NULL)
        delete [] buffer;
    
      // allocate new memory
      buffer = new unsigned char[2];
    
      // fill the memory
      buffer[0] = 0;
      buffer[1] = 1;
    }
    
    int main()
    {
      unsigned char * buffer = NULL;
    
      foo(buffer);
    
      delete [] buffer;
      
      return 0;
    }
    won’t work because, as I explained above, the pointer is sent by value, a copy is made and when returning to main, the pointer will hold the same address as before the call to foo (in this case NULL). To achieve what you want you must pass the pointer (the buffer start address) by reference.
    Code:
    // This is the corrected code
    void foo(unsigned char* &buffer)
    {
      // delete the previous buffer
      if(buffer != NULL)
        delete [] buffer;
    
      // allocate new memory
      buffer = new unsigned char[2];
    
      // fill the memory
      buffer[0] = 0;
      buffer[1] = 1;
    }
    
    int main()
    {
      unsigned char * buffer = NULL;
    
      foo(buffer);
    
      delete [] buffer;
      
      return 0;
    }
    This will ensure that the pointer to unsigned char stored in main’s stack will be altered from within function foo().


    Last edited by cilu; May 14th, 2007 at 07:17 AM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured