7.4 — Passing arguments by address

There is one more way to pass variables to functions, and that is by address. Passing an argument by address involves passing the address of the argument variable rather than the argument variable itself. Because the argument is an address, the function parameter must be a pointer. The function can then dereference the pointer to access or change the value being pointed to.

Here is an example of a function that takes a parameter passed by address:

The above snippet prints:

nValue = 5
nValue = 6

As you can see, the function foo() changed the value of nValue through the pointer parameter pValue.

Pass by address is typically used with dynamically allocated variables and arrays. For example, the following function will print all the values in an array:

Here is an example program that calls this function:

This program prints the following:


Note that the length of the array must be passed in as a parameter, because arrays don’t keep track of how long they are. Otherwise the PrintArray() function would not know how many elements to print.

It is always a good idea to ensure parameters passed by address are not null pointers before dereferencing them. Dereferencing a null pointer will typically cause the program to crash. Here is our PrintArray() function with a null pointer check:

Advantages of passing by address:

  • It allows us to have the function change the value of the argument, which is sometimes useful
  • Because a copy of the argument is not made, it is fast, even when used with large structs or classes.
  • We can return multiple values from a function.

Disadvantages of passing by address:

  • Because literals and expressions do not have addresses, pointer arguments must be normal variables.
  • All values must be checked to see whether they are null. Trying to dereference a null value will result in a crash. It is easy to forget to do this.
  • Because dereferencing a pointer is slower than accessing a value directly, accessing arguments passed by address is slower than accessing arguments passed by value.

As you can see, pass by address and pass by reference have almost identical advantages and disadvantages. Because pass by reference is generally safer than pass by address, pass by reference should be preferred in most cases.

Passing by reference, address, and value is actually not so different

Now that you understand the basic differences between passing by reference, address, and value, let’s complicate things by simplifying them. :)

In the lesson on passing arguments by reference, we briefly mentioned that references are typically implemented by the compiler as pointers. Because of this, the only real difference between pointers and references is that references have a cleaner but more restrictive syntax. This makes references easier and safer to use, but also less flexible. This also means that pass by reference and pass by address are essentially identical in terms of efficiency.

Here’s the one that may surprise you. When you pass an address to a function, that address is actually passed by value! Because the address is passed by value, if you change the value of that address within the function, you are actually changing a temporary copy. Consequently, the original pointer address will not be changed!

Here’s a sample program that illustrates this.

Because pTempPtr receives a copy of the address of pPtr, even though we change pTempPtr, this does not change the value that pPtr points to. Consequently, this program prints


Even though the address itself is passed by value, you can still dereference that address to permanently change the value at that address! This is what differentiates pass by address (and reference) from pass by value.

The next logical question is, “What if we want to be able to change the address of an argument from within the function?”. Turns out, this is surprisingly easy. You just use pass the pointer itself by reference (effectively passing the address by reference). You already learned that values passed by reference reflect any changes made in the function back to the original arguments. So in this case, we’re telling the compiler that any changes made to the address of pTempPtr should be reflected back to pPtr! The syntax for doing a reference to a pointer is a little strange (and easy to get backwards): int *&pPtr. However, if you do get it backwards, the compiler will give you an error.

The following program illustrates using a reference to a pointer.

Note that you’ll also have to update the function prototype above main to account for the new prototype of SetToSix():

When we run the program again with this version of the function, we get:


Which shows that calling SetToSix() did indeed change the address of pPtr!

So strangely enough, the conclusion here is that references are pointers, and pointer addresses are passed by value. The value of pass by address (and reference) comes solely from the fact that we can dereference addresses to change the original arguments, which we can not do with a normal value parameter.

7.4a -- Returning values by value, reference, and address
7.3 -- Passing arguments by reference

55 comments to 7.4 — Passing arguments by address

  • Jason

    Disadvantages of passing by address:

    Because dereferencing a pointer is slower than accessing a value directly, accessing arguments passed by address is slower than accessing arguments passed by value.

    Could that sentence possibly supposed to read as follows:

    Because dereferencing a pointer is slower than accessing a value directly, accessing arguments passed by address is slower than accessing arguments passed by reference.

    I would think (am assuming) that arguments passed by value would take the longest because they have to be copied.

    [ It turns out that references are usually implemented by the compiler (under the hood) using pointers. Consequently, references aren’t any faster than addresses. They just have a nicer syntax, and are safer to use. -Alex ]

  • Jason

    I think I get it. Passing by value is slow because it does a copy. Passing by reference or address is basically the same thing, just different syntax.

    [ Correct. I’ve read that if you’re passing simple built-in variables by value, it can be as fast or faster than passing by reference or address. Generally when we talk about passing by reference or address being faster, we’re talking about for compound types (eg. structs and classes). -Alex ]

    Comparing these two programs:

    Why doesn’t the second example act as the first example. As the output would be:

    What I’ve noticed is when passing an array by address it changes the address that the pointer points to when inside the function. This causes the original value to never be changed. I guess that’s just how it works.

    [ Good question and insight. As it turns out, pointer parameters are actually passed by value. Consequently, if you try to change what a pointer points to inside a function, it’s the same as changing a variable locally -- as soon as you leave the function, it will revert back to what it was. However, if you dereference the pointer and change the value of what it points to, that won’t be reverted. If you actually want to be able to change the address that a pointer points to inside a function, the best way to do this is to pass the pointer itself by reference:

    void func(char *&address)

    Incidentally, this line of code is dangerous:

    address = "b"

    This is setting the address of the “address” variable to the address of “b”. What is the address of “b”? “b” isn’t a variable, so this doesn’t really make any sense. It probably works in this case due to the way the compiler is dealing with string literals, but I certainly wouldn’t want to trust it. -Alex ]

    Any insight on this issue? Btw, I know that char *array is not an array but a pointer, but once again it really is an array when used with strings right? Just different syntax right?

    [ In C , arrays and pointers are pretty much identical. When you declare an array, all you’re doing is setting a pointer to the beginning of your allocated memory. If I’m reading your above statement correctly, your understanding is correct. This means you can do something like this:

    and it will print ‘o’. -Alex ]

    Sorry for the double post, but the input box doesn’t work right almost everytime I use it. Most of the time it eats my pre tags too. I then have to edit my post to get it working. Just a heads up on that.

    [ I haven’t had any problems using the pre tags from the input box. I have had visual problems after editing my posts where the pre tags don’t render correctly, forcing me to refresh the page. I’d really like to move to a threaded comments model so I don’t have to respond to comments like this, but there doesn’t seem to be any good plugins for wordpress to do so. I might have to spend the time to write my own. -Alex ]

  • Jason

    Ok, the code below does act as your code does. So, what’s up with my:
    char *array = “strings” code above?

    [ I think I answered this in my response above. Let me know if it isn’t clear. -Alex ]

  • I beefed up this lesson significantly because some of the stuff mentioned in the comments here is pretty important.

  • Jason

    Awesome, I get it.

    I’d just like to say, that all made me realize that communicating C++’s logic is an artform.

  • Tom

    1. In your first example function, PrintArray, don’t you have to dereference the pnArray variable, like this??:

    2. Minor typo: “The next logical question is, “What if we want to be able to be able to change the address”

  • el-mudo

    Hi Alex, it’s me again
    There is a small error in the last example in this page, you forgot to change the comments in the code, it’s writen like that:

    // This only changes pTempPtr, not pPtr!

    but, in fact, for that example, pPtr has its memory address changed together with pTempPtr since it’s a reference to it.

  • Pieter

    I can’t get your last code (with the reference to a pointer) to work.
    The linker gives the following error :
    1>main.obj : error LNK2019: unresolved external symbol “void __cdecl SetToSix(int *)” (?SetToSix@@YAXPAH@Z) referenced in function _main
    1>D:\Users\Pieter\Documents\Visual Studio 2008\Projects\Test\Debug\Test.exe : fatal error LNK1120: 1 unresolved externals

    However, I was thinking…
    If you change pTempPtr = &nSix; to *pTempPtr = nSix; (so dereference it and then assign the value of nSix) it works as it should, except that it doesn’t change the address of pTempPtr, but rather the contents.

  • weirdolino

    I’m having trouble understanding the conclusions. Under advantages you say
    Because a copy of the argument is not made, it is fast, even when used with large structs or classes.
    and under disadvantages you say
    Because dereferencing a pointer is slower than accessing a value directly, accessing arguments passed by address is slower than accessing arguments passed by value.

    Is passing by reference/address slower or faster than by value? Does it depend on the size of the data passed to the function?

    • When we talk about speed and efficiency with regards to variables, we’re talking about two separate things:

      1) The speed of creating the variable and initializing it’s values. This cost is paid once when the variable is created, and can be significant for large classes that are copied by value. This is why large classes are better passed by pointer or reference than by value, especially if a function is called many times.

      2) The speed of accessing the value stored in the variable. This cost is paid each time the variable is accessed. Although accessing pointers and references is slower than accessing normal variables because of the dereference that takes place, in practice this is rarely a large concern unless you have some kind of loop that accesses the variable hundreds or thousands of times.

  • Ben

    Post for nothing. I found the answer before the 5 minutes.

    Thanks anyway.

  • afds

    The comment is suppose to have “pnArray” instead of pArray.

    [ Fixed! -Alex ]

  • Kukudum

    In the example you used:
    The function |

    Isn’t PrintArray(anArray, 6); supposed to be PrintArray(&anArray, 6); or am I missing something o.O

    • You are missing the fact that arrays in C++ are really just pointers. So anArray is already a pointer! PrintArray is expecting a pointer for it’s first parameter, so we can pass it anArray directly.

  • Eugene Wee

    “You are missing the fact that arrays in C++ are really just pointers.”

    More accurately, an array is converted to a pointer to its first element when it is passed as an argument to a function.

  • Gareth37

    in ch 6.6 you have this -

    This would be the conceptual equivalent of the following nonsensical example:

    so how comes in the below example we can do

    why isnt it PrintArray(anArray[], 6);
    or PrintArray(anArray[0], 6); the pointer to its first element ?
    i know these dont work because it wont compile
    but it just seems odd we are referring to arrays as
    anArray[] and then it becomes just anArray ?

    • When we declare a pointer, we use the * or [] syntax to let the compiler know that this variable is a pointer as opposed to a normal variable. However, from that point forward, we can just use the variable’s name and the compiler already knows it’s a pointer.

      So if we want to pass the array to a function that expects a pointer, all we need to do is pass the variable itself.

      It’s the same as the following:

      pX already knows it’s a pointer, so when we pass it to printPtr, we don’t need to tell the compiler that it’s a pointer again.

  • jeremy

    hi alex!
    i just want to clarify some points…im quite confused with DEREFERENCING and EVALUATING pointers.
    correct me if im wrong:

    1. my idea is that in below statement, we are assigning the pointer to POINT to the address of nFive
    int *pPtr = &nFive;
    2. on this statement:
    cout << *pPtr;
    we are DEREFERENCING the pointer?
    Kindly clarify.
    Thanks a lot

    • You are correct. We dereference a pointer to get the value of what it’s pointing at.

      int *pPtr = &nFive; // pPtr holds the address of nFive
      cout << pPtr; // prints the address of nFive cout << *pPtr; // prints the value at the address of nFive, which is whatever value was assigned to nFive

  • noviceboy

    Am having an issue with passing 2-dimensional arrays / matrices.

    When I compile and run “void PrintArray(int *pnArray, int nLength)”, it works fine, and I can manipulate the entries in pnArray[iii]

    However, when I amned to pnArray[iii][jjj], I get an error in the compiler, at this line (not at the call) which says:
    error: invalid types int[int] for array subscript

    searching the net, I see various solutions that state I haven’t declared the variable as an array in main, or called the function properly, but the error appears at the function.

    at the function call I get the error: cannot convert ‘int(*)[2] to ‘int’ for argument ‘1’ to ‘void PrintArray(int*)’ ie it cant pass the array as the function declaration expects an int only?

    am using Xcode for mac.

    PS Awesome site, thanks for your hard work.

    • Thiago Barcala

      I had the same problem you’re having. I resolved this by doing the following:


      I don’t know if this is the best way (or even the right) to do this, but works!

      • vipul

        please understand this clearfully
        int main()
        int anTest[][3] =
        {1, 2, 3},
        {4, 5, 6},
        {7, 8, 9}
        PrintArray(anTest[0], 3, 3);---->where is 3,3 supposed to?

  • Tom

    RE: The final code about changing the address of an argument from within the function.

    You change the address of pPtr from &nFive to &nSix. Is this a memory leak?


    • Bhupathi

      Hi Tom,
      This is not a memory leak as the variables nFive and nSix are in the stack. The stack will be cleared on process termination.


  • Bob

    Excuse me but I don’t understand the difference between


    Don’t they both do the same thing? Why bother with the top one (which is more complicated in my opinion) when you can just do the second one?

    • Daniel

      Let me give an example:

      The output of this program is “01134” not “01234” as you might expect. This is because in “PassPointerByValue2″ only a local copy of the pointer “thing” is changed whereas in “PassPointerByReference4″ the actual pointer “stuff” is changed. Because a pass by reference was used, “thing” was “stuff” not a copy of “stuff” it was “stuff”. I hope that helps you see the difference. (^.^)

      • ming

        This example is very good for study passing pointer in different cases. I spent a hour to get understand it and finally feel comfortable about pointer.
        Here is my explanation of this code:

        Hope this is useful 😀

  • Cuacharpanas

    If string literals don’t have addresses what happen when I write this code which runs without errors from the compiler:

    What str points to?? Moreover, it works the same when a literal string is passed as an argument to a function:

    display(“Important message!”);

    where display definition is:

    someplace str must point to, I think. The prototype void display(char str[]) also works, what is the difference??, may be str is considered as an array, however i tried to change the location it points to and get no error, It worked!

    Hope for replies, Thanks a lot and congratulations for the tutorial, it’s clear and extensive.

  • Intelus

    I’d like to ask a question. In this post (7.4), you say:

    Note that the length of the array must be passed in as a parameter, because arrays don’t keep track of how long they are. Otherwise the PrintArray() function would not know how many elements to print.

    Also, in your reply to Kukudum’s comment, you said:

    You are missing the fact that arrays in C++ are really just pointers. So anArray is already a pointer! PrintArray is expecting a pointer for it’s first parameter, so we can pass it anArray directly.

    Examine this short program (explanation below):

    This prints:

    Now, apparently, main() is somehow aware of the fact that anArray is an array with 6 elements while function() sees nothing more than a single address (pointer). Changing the data type yields the same result - pnArray is always 4 bytes (as pointers should be on 32-bit computers) while sizeof(anArray) returns the size of the array’s elements put together (ex. 12 bytes for short, assuming there are 6 elements).

    So I’m wondering, why does main() consider it an array and where is this information stored?

    By the way, regarding the PrintArray function… Wouldn’t it be better to write something like ” if (anArray) PrintArray(…);” inside main() instead of making a null pointer check inside PrintArray? Time is wasted on making a function call which won’t do anything. If it makes the code too complex, you can always use an inline function.

    • bla

      I would like to know the answer to your (first) question too. Because s. th. like:

      would be nice to make the function PrintArray more elegant as it would only require one parameter:

  • rebelsoul

    Hi Alex,

    I am having a problem compiling reference to a pointer example code. I am following your code example, however i am getting error while initializing reference to a pointer in main.

    I am getting following errors on VS 2008

    • rebelsoul

      I have found the problem and it was that i was passing address of a variable in my function call e.g.

      However, still i am getting error while compiling my code. I am enclosing a clean code.

      Please reply me and guide me what i am doing wrong.

  • prashant wavkhede

    write a function power to return x to power y, if arguments are (x,y) and to return square of x if argument is (x).

  • Hello there.
    I’m new to C++ (as will soon become obvious!), and I don’t understand why the following function (the second block of code on the tutorial above) prints the CONTENTS of pnArray…

    void PrintArray(int *pnArray, int nLength)
    for (int iii=0; iii < nLength; iii++)
    cout << pnArray[iii] << endl;

    Shouldn't the 'pnArray[iii]' part be dereferenced (ie; '*pnArray[iii]')to get the values IN the pointer array? Or does it not work like that with pointer arrays? Clearly there's something I'm not getting!
    Any help, well appreciated.
    Thanks for all the great tutorials. You have a great way of explaining concepts step by step!

  • Matt

    I just found out that you have to pass arrays to functions as pointers.

  • moon1212

    • Q.1 write a the c program using a function method to calculation the area and perimeter for the rectangle and the square by any given width and height . the program should ask the user to stop or retry the program with other values .

    Q.2 write a program in c language using a function method to calculate the following series and give the result;
    X= n^1*n^2*n^3*…………* n^k
    Where n&k are any number given by the user
    pls… help me

  • kriain1982


    First of all thanks for the tutorials. But I found some thing interesting as below.


    using namespace std;
    int five = 5;
    int six = 6;

    void check(int *temp)
    printf(“\n*temp : %d\n”, *temp);
    *temp = six;
    printf(“\n*temp : %d\n”, *temp);

    int main()
    int *ptr = &five;
    printf(“\nValue in ptr : %d\n”, *ptr);
    printf(“\nValue in ptr : %d\n”, *ptr);
    return 0;

    see the Output :

    Value in ptr : 5

    *temp : 5

    *temp : 6

    Value in ptr : 6

    So, even I am sending pointer (by value), *ptr is getting modified. How can you explain this?

  • zidane3x3

    Thank so much, i used pointer like this (*&pTempPtr) for my program without understanding clearly why but now i get it :-) .

  • youssef dirani

    “The syntax for doing a reference to a pointer is a little strange (and easy to get backwards”
    What’s the meaning of “easy to get backwards”?

    • Alex

      The correct syntax for a pointer reference is *&pPtr. For a non-pointer variable, you’d create a reference to it like this: &nFoo. Since a pointer is declared as *pPtr, you’d think the correct syntax for a pointer reference should be &*pPtr, with the ampersand on the outside. But it isn’t so.

  • Abarajithan

    Well, I understood something like this as a reason for why the use of ref over variables is slower for smaller datatypes. Tell me if I’m right.

    In a 64 bit machine, an address is 8 bytes, while an int is 4 bytes. So, it takes more time to copy an address than to copy an int. Plus, there’s the time taken for deref-ing as u mentioned. As a result, performance wise, passing by variables is better for smaller size variables while passing by ref is better for bigger structs and classes.

    Another question. If array is really a pointer and if it cannot keep track of its own length, how does sizeof() return the total correct size of arrays?

  • Todd


    Your function "PrintArray()" should be named "printArray()" by naming conventions. You reference this function 5 times in your lesson (text & code). Same goes for "SetToSix()" (appears 9 times in your code/text).

    By the way, you gave a fantastic explanation of these three different ways of passing arguments and how they all relate to each other.

  • Shivam Tripathi

    Alex…what’s the analysis of this code…plz tell in-depth…O/P is 1   5   1   8….moreover when x & y are coming out of the scope how the pointers are dereferencing them…isn’t they produce DANGLING POINTERS??…plz help

    • Alex

      The pointers will still point to the memory addresses occupied by the (now out of scope) local variables. The contents of those memory locations may still contain the values put there by the local variables -- or they may not.

      So yes, this is a case where the pointers are left dangling (pointing to memory that has been deallocated).

      • Shivam Tripathi

        hmm…got it…it means that although any variable goes out of scope but it’s value may-be still accessible until the OS replaces that stack portion with some other sibling block…correct me if m wrong???

        Moreover…i hv a confusion regarding the pass of the address by reference..consider this snippet:

        Plz..answer both sections…

Leave a Comment




seventeen + 2 =

Put C++ code inside [code][/code] tags to use the syntax highlighter