In this lecture...
Intro to Pointers. Pointer Arithmetic. Dynamic Memory Management. pages 15-23 in the textbook.
Objects are referenced through their names. We use variables to name an object. There are three different choices of variable that we use to access an object - value, pointer and reference.
A Value variable is a variable that names the object itself. Objects may be declared as:
We can declare value variables with an initial valuetype_name object_name;
To access the object, you just use its name:int number( 5 ); float average( 90.3 ); string person( "Sam" );
int number = 5; float average = 90.3; string person = "Sam";
A Pointer variable stores the address of object. Pointers may be declared as:
Each variable being declared as a pointer must be preceded by an asterik (*). Typical declarations:type_name *pointer_name;
int *number; string *person;
A Reference variable looks like a pointer but acts like a value variable. References may be declared as:
Typical declaration:type_name object_name; type_name &reference_name( object_name );
The reference variable stores the address of the object, and that address cannot be changed. Reference variable are normally not used to declare variables. They are used more often as function parameters and as function return types.int number = 5; int &ref_number = number;
Pointer variables contain memory addresses as their values. Using pointers we have an indirect reference to the value. Consider the example,
Since p is a pointer, only an address can be assigned to it. The &, or address operator, returns the address. The following statement assigns the address of the variable a to pointer variable p:int a = 1, b = 2; int *p;
The variables a, b and *p have the same value: 1. The * operator is called dereferencing operator. Note, p holds the address of a, *p holds the value of a. By dereferencing a pointer, we can indirectly change the value of a:p = &a; /* p now points to a */ b = *p; /* b now is 1 */
The variable b is 1. The following figure illustrates the pointer operation.*p = 3; /* a now is 3 */
Example.
int x = 1; int * p, * q; p = &x; /* p now points to x */ q = p; /* q now also points to x */ *q += 2; /* x is now 3 */ *p = 5; /* x is now 5 */
Exercise. What is the output of the following segment of code?
int n = 5; int *p = &n; int k = *p; n++; *p += 1; p = &k; cout << n << ' ' << *p << ' ' << k << ' ' << endl;
The only legal arithmetic operators on pointers are adding or subtracting an integer, or subtracting one pointer from another. Pointer arithmetic is automatically done in units of the pointer's underlying base type. This is why we need to identify the type of variable that a pointer points to, as in:
int *ptr;
ptr + 1;
any_type *ptr;
The increment and decrement operators.
*ptr++ is equivalent to *(ptr++)
*(ptr++) and (*ptr)++
Example.
string s = "online"; char *p = &s[0]; cout << p << endl; p+2; cout << p << endl; (*p)++; cout << p << endl;
Null pointer.
NULL is a special value (usually defined as zero) which points to nowhere.
Therefore, if a pointer contains the address NULL, it means that it contains an
invalid address and you are not supposed to dereference it. In other words, a NULL pointer value means that the data it points to is
undefined.
The new operator creates an object of the proper size:
type_name *ptr = new type_name;
To free the space you must call operator delete. Delete automatically call the destructor for an object.
delete ptr;
Example.
string *s; s = new string("15-113"); cout << s << endl; delete s;
int *ptr = new int[10];
delete [] ptr;
Example.
int *s; int *p; s = new int[10]; /* allocate space */ p = s; for(int i=0;i<10;i++) *p++ = i; /* initialize the array */ delete [] s; /* free space */
Stale pointer.
One object can have several pointers pointing at it. Consider the following figure. After the call to delete two pointers p and q no longer point to valid data. Since that chunk of memory is freed, the system can write to there any other information, so that next time you dereference p or q it would lead to unpredictable results.
Double delete.
Too many deletes is as bad as too few deletes. The following code will lead to a run-time error:
int *p = new int(10); int *q = p; delete p; delete q;
Some further examples of the pointer declaration:
int *value( new int( 7 ) ); float *final_grade( new float( 94.3 ) ); myString *prompt( new myString( "Enter an integer: " );
Last updated January 18, 2001.
![]() |
Please send corrections to Victor
S. Adamchik,
Computer Science Department, Carnegie Mellon University, Pittsburgh, PA. |