Advanced Pointers
I. In-Class Exercises
Programming Exercises
II. Knowledge Summary
✨ Array Pointers
Pointing to a Static 1D Array
In C++, an array name is essentially a pointer to the first element of the array. Therefore, array elements can be accessed through pointers.
1#include <iostream>
2using namespace std;
3
4int main() {
5 int arr[5] = {1, 2, 3, 4, 5}; // define an array of 5 integers
6 int *p = arr; // the array name is a pointer to the first element
7
8 // Access elements through the pointer
9 for (int i = 0; i < 5; ++i) {
10 cout << "*(p + " << i << ") = " << *(p + i) << endl;
11 }
12
13 return 0;
14}Key points:
- The array name
arris a pointer to the first element of the array.arris equivalent to&arr[0] - Array elements can be accessed through pointers just like using array indexing.
*(arr + i)is equivalent toarr[i]
Pointing to a Dynamically Allocated 1D Array
You can use the new operator to dynamically allocate a 1D array and use the delete[] operator to release the dynamically allocated memory.
1#include <iostream>
2using namespace std;
3
4int main() {
5 int n;
6 cout << "Enter the size of the array: ";
7 cin >> n;
8
9 // Dynamically allocate a 1D array
10 int* arr = new int[n];
11
12 // Initialize the array
13 cout << "Enter " << n << " elements:" << endl;
14 for (int i = 0; i < n; ++i) {
15 cin >> arr[i];
16 }
17
18 // Output the array
19 cout << "The array is:" << endl;
20 for (int i = 0; i < n; ++i) {
21 cout << arr[i] << " ";
22 }
23 cout << endl;
24
25 // Release the dynamically allocated memory
26 delete[] arr;
27
28 return 0;
29}✨ Const Pointers
Const pointers and pointers to constants are two different uses of pointers, commonly used to protect data from being modified.
Pointer to Constant
A pointer to constant is a pointer that points to constant data, meaning the data pointed to cannot be modified through this pointer, but the pointer itself can be changed to point to a different address.
const int *p;Here p is a pointer to const int data. The integer value pointed to cannot be modified through p, but p itself can be changed to point to another address.
1#include <iostream>
2using namespace std;
3
4int main() {
5 int a = 10;
6 int b = 20;
7 const int *p = &a; // p points to a, but cannot modify a's value through p
8
9 cout << "Value pointed to by p: " << *p << endl;
10
11 // *p = 15; // Error: cannot modify a's value through p
12 p = &b; // Legal: can change where p points
13 cout << "Value pointed to by p: " << *p << endl;
14
15 return 0;
16}Constant Pointer
A constant pointer is a pointer that is itself a constant, meaning the address the pointer points to cannot be changed, but the data at that address can be modified through the pointer.
int *const p;This means p is a constant pointer to int data. The integer value can be modified through p, but p itself cannot be changed to point elsewhere.
1#include <iostream>
2using namespace std;
3
4int main() {
5 int a = 10;
6 int *const p = &a; // p is a constant pointer, pointing to a
7
8 cout << "Value pointed to by p: " << *p << endl;
9
10 *p = 15; // Legal: can modify a's value through p
11 cout << "Value pointed to by p: " << *p << endl;
12
13 // int b = 20;
14 // p = &b; // Error: cannot change where p points
15
16 return 0;
17}Constant Pointer to Constant
This type of pointer both points to constant data and is itself a constant. That is: the data cannot be modified through the pointer, and the pointer's target cannot be changed either.
const int *const p;This means p is a constant pointer to const int data. Neither the integer value can be modified through p, nor can p itself be changed to point elsewhere.
1#include <iostream>
2using namespace std;
3
4int main() {
5 int a = 10;
6 const int *const p = &a; // p is a constant pointer to const int
7
8 cout << "Value pointed to by p: " << *p << endl;
9
10 // *p = 15; // Error: cannot modify a's value through p
11 // int b = 20;
12 // p = &b; // Error: cannot change where p points
13
14 return 0;
15}const Summary
Comparison of four pointer types:
| Pointer Type | Name | Can Change Target Address | Can Modify Data at Target Address |
|---|---|---|---|
int *pointer | Regular pointer | Yes | Yes |
const int *pointer | Pointer to constant | Yes | No |
int *const pointer | Constant pointer | No | Yes |
const int *const pointer | Constant pointer to constant | No | No |
✨ Struct Pointers
You can use a pointer to point to a struct variable and access and modify the struct's members through the pointer. There are two ways to access members of a struct pointer: using the arrow operator -> or using (*ptr).member.
1#include <iostream>
2using namespace std;
3
4// Define a struct representing a point
5struct Point {
6 int x; // x coordinate
7 int y; // y coordinate
8};
9
10int main() {
11 Point p1;
12 p1.x = 10;
13 p1.y = 20;
14
15 // Define a pointer to a struct
16 Point *p_ptr;
17 p_ptr = &p1; // assign the address of struct variable p1 to pointer p_ptr
18
19 // Access struct members through the pointer
20 cout << "Point p1: (" << p_ptr->x << ", " << p_ptr->y << ")" << endl;
21 cout << "Point p1: (" << (*p_ptr).x << ", " << (*p_ptr).y << ")" << endl;
22
23 // Modify struct member values
24 p_ptr->x = 30;
25 p_ptr->y = 40;
26 cout << "Modified Point p1: (" << p1.x << ", " << p1.y << ")" << endl;
27
28 return 0;
29}You can use pointers to dynamically allocate struct memory. In C++, use the new keyword to dynamically allocate memory and delete to release it.
1#include <iostream>
2using namespace std;
3
4// Define a struct representing a point
5struct Point {
6 int x; // x coordinate
7 int y; // y coordinate
8};
9
10int main() {
11 // Dynamically allocate struct memory
12 Point *p_ptr = new Point;
13
14 // Set struct member values
15 p_ptr->x = 10;
16 p_ptr->y = 20;
17
18 // Access struct members through the pointer
19 cout << "Point: (" << p_ptr->x << ", " << p_ptr->y << ")" << endl;
20 cout << "Point p1: (" << (*p_ptr).x << ", " << (*p_ptr).y << ")" << endl;
21
22 // Release the dynamically allocated memory
23 delete p_ptr;
24
25 return 0;
26}✨ Execution Examples for Pointers
The following memory diagrams illustrate how array pointers, const pointers, and struct pointers work.
Example 1: Relationship Between Array Names and Pointers
int arr[5] = {10, 20, 30, 40, 50};
int *p = arr;1Memory layout:
2Address (illustration) 0x1000 0x1004 0x1008 0x100C 0x1010
3 +-------+-------+-------+-------+-------+
4arr: | 10 | 20 | 30 | 40 | 50 |
5 +-------+-------+-------+-------+-------+
6 arr[0] arr[1] arr[2] arr[3] arr[4]
7
8p = arr = &arr[0] = 0x1000Pointer arithmetic execution process:
p -> address 0x1000, *p = 10 equivalent to arr[0]
p + 1 -> address 0x1004, *(p+1) = 20 equivalent to arr[1]
p + 2 -> address 0x1008, *(p+2) = 30 equivalent to arr[2]
p + 3 -> address 0x100C, *(p+3) = 40 equivalent to arr[3]
p + 4 -> address 0x1010, *(p+4) = 50 equivalent to arr[4]
p + idoes not simply add i to the address; it addsi * sizeof(int)bytes. Sinceintoccupies 4 bytes,p + 1actually increases the address by 4.
Example 2: Allocation and Release of a Dynamic Array
1int n = 5;
2int *arr = new int[n]; // dynamically allocate an array of 5 ints
3
4for (int i = 0; i < n; ++i) {
5 arr[i] = (i + 1) * 10;
6}
7// arr: [10, 20, 30, 40, 50]
8
9delete[] arr; // release the entire array (use delete[], not delete)
10arr = nullptr;1After new int[5]:
2Heap memory: [ 10 | 20 | 30 | 40 | 50 ]
3 arr points here
4
5After delete[] arr:
6Heap memory: [ ? | ? | ? | ? | ? ] <- releasedExample 3: Behavior Comparison of const Pointers
1int a = 10, b = 20;
2
3// Regular pointer: address can change, data can change
4int *p1 = &a;
5*p1 = 15; // ✓ can modify data
6p1 = &b; // ✓ can change target
7
8// Pointer to constant: address can change, data cannot change
9const int *p2 = &a;
10// *p2 = 15; // ✗ cannot modify data through p2
11p2 = &b; // ✓ can change target
12
13// Constant pointer: address cannot change, data can change
14int *const p3 = &a;
15*p3 = 15; // ✓ can modify data
16// p3 = &b; // ✗ cannot change target
17
18// Constant pointer to constant: neither can change
19const int *const p4 = &a;
20// *p4 = 15; // ✗ cannot modify data
21// p4 = &b; // ✗ cannot change targetMemory trick:
constto the left of*means data cannot be modified;constto the right of*means the target cannot be changed.
Example 4: Two Ways to Access Struct Pointer Members
struct Point { int x; int y; };
Point p1 = {10, 20};
Point *ptr = &p1;1Memory layout:
2p1 [0x1000]: x=10, y=20
3ptr[0x2000]: 0x1000 (points to p1)
4
5Two equivalent ways to access members:
6ptr->x equivalent to (*ptr).x both give 10
7ptr->y equivalent to (*ptr).y both give 20Using
->is more concise than(*ptr).xand is the recommended way to access struct members through pointers.
✨ Problem-Solving Steps for Pointers
General approach for solving problems using advanced pointer knowledge:
- Arrays and pointers are interchangeable: When a function parameter requires a pointer, you can pass an array name directly; when traversing an array, you can use a pointer instead of an index
- Choose appropriate const qualifiers: If a function only needs to read data without modifying it, declare the parameter as
const int *pto prevent accidental modification - Dynamic array workflow:
newto allocate -> use ->delete[]to release -> set tonullptr - Struct pointer operations: Use the
->operator to access members; create dynamic structs withnew, release withdelete
✨ Common Mistakes with Pointers
- Mixing
deleteanddelete[]: An array allocated withnew int[n]must be released withdelete[] arr. Usingdelete arrwill cause memory leaks or program crashes - Out-of-bounds pointer access:
*(p + 5)accesses memory outside the array range (if the array only has 5 elements), which is undefined behavior - Confusing const modifier placement:
const int *p(data cannot be modified) andint *const p(target cannot be changed) have completely different meanings. Writing them wrong may not cause a compiler error but will lead to logic errors - Forgetting to use
->or(*ptr).with struct pointers: Writingptr.xis incorrect becauseptris a pointer, not a struct variable - Forgetting to release after dynamic allocation: Every
newmust have a correspondingdelete; otherwise memory leaks occur. This is especially important in loops
III. Homework
Knowledge Quiz
- Advanced Pointers - Quiz## Programming Exercises