Unlike pass-by-value, which is common computer science term, pass-by-pointer is a less-than-official term the text uses to label a special case of pass-by-value. Also known as pass-by-address, it describes the situation where the passed value is the address of a data item, and the parameter is a pointer variable. Although the terms are unofficial, experienced C++ programmers understand the implied passing technique. These terms allow us to talk about this passing method more easily and distinguish its syntax and behavior from the other methods.
The arguments in a pass-by-value function call can be any arbitrary expression, but pass-by-pointer only allows one kind of expression: a memory address. Programmers can formulate the expressions in many ways based on arbitrarily complex arithmetic operations, but they typically rely on only three basic patterns. To help classify the expressions, assume a function named function, a variable named variable, and a structure or class called Person.
function(&variable)
.new
operator allocates memory on the heap and returns its address, allowing programmers to use it as an expression: function(new Person);
This discussion uses the same technique of articulating C++ statements with a time-varying illustration of memory contents as used in the previous section. Although the changes from pass-by-value to pass-by-pointer are subtle, they are significant, so you must compare the programs carefully. The addresses of variables a (0x12) and b are still arbitrary but play a larger role in this example: the program passes the address of a to the pointer variable p, and while p has an address, its contents are also an address - the address of a.
As in the previous example, simple data are any of the fundamental, built-in data types like char, int, or double. While the example presented below uses an int, the code will exhibit the same behavior with any fundamental data type.
void func(int* p); int main() { int a = 5; // step 1 func(&a); // step 2 } void func(int* p) { *p = *p + 1; // step 3 } // step 4 |
![]() |
(a) | (b) |
&
) function func is called and the address of a (the value 0x12) is passed from the call to the local (pointer) variable p (in essence: int* p = &a;). Notice that while the function is active, *p is an alias for a (they represent the same variable). It is common to illustrate that p points to a with an arrow drawn from p to a*
). The function increments the value in a (look at that closely - it increments a and NOT p)As before, structured data are typically instances of structures or classes. In addition to reviewing the sections recommended above, it may also be a good idea to review the arrow operator before studying the next example.
struct part { char type; int id; }; void func(part* p); int main() { part a = { 'd', 10 }; // step 1 func(&a); // step 2 } void func(part* p) { p->id = 1000; // step 3 } // step 4 |
![]() |
*
and .
; it both dereferences p and selects idPassing data to a function by pointer is more complex than passing it by value, sometimes making it difficult to categorize a difference as an advantage or disadvantage. When considering the relative merits of the two methods, pass-by-pointer has three notable characteristics. The first is a benefit, the second a drawback, and the third depends on what the problem solution needs.
int u; ... read(&u); // Get the address of the variable in the function call ... void read(int* v) // Make the parameter a pointer in the definition and prototype { cin >> *v; // Dereference the pointer parameter everywhere it's use in the function cout << *v << endl; }The compiler may not always detect a missed operation, but the program will fail nevertheless!
new
, is challenging. Neglecting to deallocate heap memory somewhere in the program causes a memory leak.10
, a + b
, and sqrt(x)
as arguments, but none of these have an address, so the program can't pass them by pointer.const
, preventing changes by the function.