Andy Wang Object Oriented Programming in C++ COP 3330 Pointer Basics Andy Wang Object Oriented Programming in C++ COP 3330
What is a Pointer? A variable that stores a memory address To declare a pointer use the * operator with the following format typeName *variableName; int n; int *p; // pointer to an int All pointers (memory addresses) have the same size. Thus, the type information is important to distinguish them from one another double *dptr; // pointer to a double char *cpt1; // pointer to a char float *fptr; // pointer to a flot
Note These three declarations are equivalent int *p; int * p; int* p; Tricky when declaring multiple variables int x, y, z; // three variables of type int int* p, q, r; // one pointer to int and two integers int *p, *q, *r; // three pointers to int
Pointer Dereferencing To access the target pointed by the pointer, we need to dereference the pointer with the unary * operator int *ptr; // a pointer to int ptr is a variable holding a memory address of an int *ptr dereferences the pointer, which points to the int Note When declaring a pointer, you need to use the * operator AFTER that, you use * only to dereferencing the pointer A pointer may not point to a valid target A pointer may not be initialized Can get runtime error message “segmentation fault”
Pointer Example http://www.cs.fsu.edu/~myers/c++/examples/pointers /pdeclare.cpp
Pointer Example #include <iostream> using namespace std; int main() { int *ptr1, *ptr2; double *dptr; cout << “The value of ptr1 = “ << ptr1 << endl; cout << “The value of ptr2 = “ << ptr2 << endl; cout << “The value of dptr = “ << dptr << endl; // DANGEROUS! Deferecing uninitialized pointers cout << “*ptr1 = “ << *ptr1 << endl; cout << “*ptr2 = “ << *ptr2 << endl; cout << “*dptr = “ << *dptr << endl; }
Initializing Pointers What can we assign to pointers at initialization time? Null Pointers of the same type Address of an variable of the same type
Null Pointer 0 is also known as the null pointer The only integer literal that may be assigned to a pointer int *p = 0; // okay int *q; q = 0; // okay int *z; z = 900; // BAD! A null pointer is never a valid target If you deference a null pointer, you will get a segmentation fault We use null instead of random memory addresses, so we know currently the pointer is not pointing to a valid target To check, do the following if (ptr != 0) cout << *ptr;
Null Pointer Example http://www.cs.fsu.edu/~myers/c++/examples/pointers /pnull.cpp
Null Pointer Example #include <iostream> using namespace std; int main() { int *ptr; cout << “The value of ptr = “ << ptr << endl; cout << “Now initializing ptr to null pointer” << endl; ptr = 0; if (ptr == 0) cout << “Pointer unsafe to dereference” << endl; else cout << “Pointer is safe to dereference” << endl; cout << “Attempting to dereference ptr” << endl; cout << “*ptr = “ << *ptr << endl; }
Pointers of the Same Type Legal to assign pointers of the same type int *ptr1, *ptr2; ptr1 = ptr2 // okay Although all pointers are addresses, different types of pointers are treated differently Automatic type coercisons do not apply int *ip; char *cp; ip = cp; // ILLEGAL To force a coercion, perform an explicit cast ip = reinterpret_castint<int *>(cp) // better know what you // are doing
The “Address of” Operator Recall the unary operator &, applied to a variable, gives its address int *ptr; int num; ptr = # // assign the address of num to ptr
Address of Operator Example http://www.cs.fsu.edu/~myers/c++/examples/pointers /pinit.cpp
Address of Operator Example #include <iostream> using namespace std; int main() { int *ip1, *ip2; double *dp1, *dp2; char *cp1, *cp2; int x = 5; double a = 1.1; char ch = ‘$’; ip2 = &x; dp2 = &a; cp2 = &ch;
Address of Operator Example cout << “ip2 = “ << ip2 << “\t &x = “ << &x << endl; cout << “dp2 = “ << dp2 << “\t &a = “ << &a << endl; cout << “cp2 = “ << cp2 << “\t &ch = “ << &ch << endl; cout << “cp2 = “ << reinterpret_cast<void *>(cp2) << “\t &ch = “ << reinterpret_cast<void *>(&ch) << endl << endl; cout << “*ip2 = “ << *ip2 << “\t x = “ << x << endl; cout << “*dp2 = “ << *dp2 << “\t a = “ << a << endl; cout << “*cp2 = “ << *cp2 << “\t ch = “ << ch << “\n\n”; ip1 = ip2; dp1 = dp2; cp1 = cp2; Would try to print a null terminated char string
Address of Operator Example cout << “ip1 points to “ << *ip1 << endl; cout << “dp1 points to “ << *dp1 << endl; cout << “cp1 points to “ << *cp1 << endl; // ATTEMPTING ILLEGAL OPERATIONS /* ip1 = cp1; dp1 = ip1; cp1 = &a; */
Address of Operator Example dp1 = reinterpret_cast<double *>(ip2); ip1 = reinterpret_cast<int *>(dp2); cout << “ip1 points to “ << *ip1 << endl; cout << “dp1 points to “ << *dp1 << endl; cout << “\nip2 = “ << ip2 << endl; cout << “&*ip2 = “ << &*ip2 << endl << endl; cout << “x = “ << x << endl; cout << “*&x = “ << *&x << endl; return 0; }
Array Variables and Pointer Variables Array variable is just a kind of a pointer variable, pointing to the first indexed variable of the array int a[10]; int *p, *p2 = 0; Since both are pointers, it is okay to do the following p = a; // p points to the starting location of a[10] Thus p[0] is the same as a[0] However, the following is illegal a = p2; // ILLEGAL The type of a is const version of int *, which cannot be changed