Skip to content

Commit 1fd8257

Browse files
committed
Update chapter 5
1 parent e1a9654 commit 1fd8257

14 files changed

+214
-21
lines changed

README.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
# Programming in C/C++ Efficiently
22

3-
`If you are a publisher and would like to publish the textbook worldwide, you can contact Prof. Shiqi Yu <[email protected]>.`
4-
53
Course 'CS205 C/C++ Program Design' in 2021 Fall at Southern University of Science and Technology. The lecture videos can be found at https://www.bilibili.com/video/BV1Vf4y1P7pq
64

75
## [Chapter 1: Getting Started](week01/README.md)

week05/Lecture05.pptx

-28 Bytes
Binary file not shown.

week05/README.md

Lines changed: 199 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,211 @@
1-
# Chapter 5: Memory and Pointer
1+
# Chapter 5: Pointers and Dynamic Memory Management
2+
3+
A pointer in C/C++ can be used to access a specific memory location, and has very good efficiency. It is one of the unique advantages of C/C++, and also is a challenging knowledge point. You must be very careful to use it. Otherwise, some bugs will tend to be introduced.
24

35
## Pointers
46

5-
## Pointers and Arrays
7+
Firstly, we should understand that a pointer is a variable for an address. Like other kinds of variables, a pointer has its own value, and the value is an address in the memory.
68

7-
## Allocate memory: C style
9+
There is an operator `&` which can return the address of a variable or an object. If we have `int num = 10;`, we can get the address of `num` by `&num`. So we can declare a pointer and assign an address to it.
810

9-
## Allocate memory: C++ style
11+
```C++
12+
int num = 10;
13+
int * p1 = NULL, * p2 = NULL; // declaration two pointers, initialized to 0
14+
p1 = &num; // take the address of num, assign to p1
15+
p2 = &num; // take the address of num, assign to p2
16+
*p1 = 20; // assign 20 to num
17+
*p2 = 30; // assign 20 to num
18+
```
19+
20+
![Two pointers point to the same memory which address is 0xABCDEF00.](images/pointer.png)
21+
22+
In the previous source code, two pointers `p1` and `p2` are declared. Both of them are assigned the address of `num`. It means the two pointers point to the same memory, and the two pointers regards there is an `int` at that position of the memory.
23+
24+
Another operator here is `*` which is for pointer dereference. It can dereference the pointer a to access the object. The following two lines are equivalent since `p1` is a pointer to `num`.
25+
26+
```C++
27+
*p1 = 20;
28+
num = 20;
29+
```
30+
31+
Pointers can not only point to some fundamental types such as `int`, `float`, they can also point to objects of structures or objects, and even functions. In the following code, a structure `stu` is declared and initialized. Then its address is initialized to a pointer `pStu`. The structure and the pointer is illustrated in the figure.
32+
33+
Since `stu` is a structure, we can use `.` like `stu.name` to access its members. We can also use the pointer of `stu` to do that. The operator will be `->`, not be `.`. `stu.name` is equivalent to `pStu->name`.
34+
35+
```C++
36+
struct Student
37+
{
38+
char name[4];
39+
int born;
40+
bool male;
41+
};
42+
//declare and initialize a structure
43+
Student stu = {"Yu", 2000, true};
44+
//assign the address of stu to pStu
45+
Student * pStu = &stu;
46+
//change members of the structure through pointer pStu
47+
strncpy(pStu->name, "Li", 4);
48+
pStu->born = 2001;
49+
(*pStu).born = 2002;
50+
pStu->male = false;
51+
```
52+
53+
![Pointer pStu points to a structure in memory which contains three members, name, born and male.](images/pointer-struct.png)
54+
55+
The address value contained in pointer can be printed out.
56+
```C++
57+
printf("Address of stu: %p\n", pStu); //C style
58+
cout << "Address of stu: " << pStu << endl; //C++ style
59+
cout << "Address of stu: " << &stu << endl;
60+
cout << "Address of member name: " << &(pStu->name) << endl;
61+
cout << "Address of member born: " << &(pStu->born) << endl;
62+
cout << "Address of member male: " << &(pStu->male) << endl;
63+
```
64+
65+
The address is an unsigned integer. It is a 32-bit unsigned integer on most 32-bit OS, and a 64-bit unsigned integer for most current 64-bit systems. You can run the following code to check how many bits your system uses for addresses.
66+
67+
```C++
68+
cout << "sizeof(int *) = " << sizeof(int *) << endl; // 4 or 8
69+
cout << "sizeof(Student *) = " << sizeof(Student *) << endl; // 4 or 8
70+
cout << "sizeof(pStu) = " << sizeof(pStu) << endl; // 4 or 8
71+
```
72+
73+
### Pointers of Pointers
74+
75+
Since a pointer is a variable, the variable will also be stored in memory and has its own address. Then another pointer can also point to this pointer. The figure shows the variable `num` in the example source code. Pointer `p` points to `num`, and Pointer `pp` points to `p`. `*(*pp) = 20` will change the value of number to `20`.
76+
77+
![Pointer `pp` points to `p`, and pointer `p` points to `num`.](images/pointer-pointer.png)
78+
79+
```C++
80+
//pointer-pointer.cpp
81+
#include <iostream>
82+
using namespace std;
83+
84+
int main()
85+
{
86+
int num = 10;
87+
int * p = &num;
88+
int ** pp = &p;
89+
*(*pp) = 20;
90+
91+
cout << "num = " << num << endl;
92+
93+
return 0;
94+
}
95+
```
96+
97+
### Constant pointers
98+
99+
If the `const` type qualifier is put before a fundamental type like `const int num = 1;`, the value of `num` cannot be changed after its initialization.
100+
101+
If `const` is put before the type name of a pointer as in the following example, you cannot change the value that the pointer points to.
102+
103+
```C++
104+
int num = 1;
105+
//You cannot change the value that p1 points to through p1
106+
const int * p1 = &num;
107+
*p1 = 3; //error
108+
num = 3; //okay
109+
```
10110

111+
But you can change the pointer itself.
11112

12-
`const int * p; int * const p;`
113+
```C++
114+
p1 = &another; //okay
115+
```
116+
117+
`const` can also be put between `*` and the name. If so, the pointer will alway point to that memory, cannot pointer to other places. But the value in that memory can be changed.
118+
119+
```C++
120+
//You cannot change value of p2 (address)
121+
int * const p2 = &num;
122+
*p2 = 3; //okay
123+
p2 = &another; //error
124+
```
125+
126+
If two `const` are used as follows, then neither the address nor the value can be changed.
127+
```C++
128+
//You can change neither
129+
const int* const p3 = &num;
130+
*p3 = 3; //error
131+
p3 = &another; // error
132+
```
133+
134+
### Pointers and Arrays
135+
136+
The elements in an array are also stored in memory and have their addresses. The following code shows how to get the addresses of the first 4 elements in an array and assign them to 4 pointer variables. After printing out the addresses, you can find those addresses have an interval of `sizeof(Student)`. Member `born` of the second element can be accessed by `students[1].born` or `p1->born`.
137+
138+
```C++
139+
//pointer-array.cpp
140+
Student students[128];
141+
Student * p0 = &students[0];
142+
Student * p1 = &students[1];
143+
Student * p2 = &students[2];
144+
Student * p3 = &students[3];
145+
146+
printf("p0 = %p\n", p0);
147+
printf("p1 = %p\n", p1);
148+
printf("p2 = %p\n", p2);
149+
printf("p3 = %p\n", p3);
150+
151+
//the same behavior
152+
students[1].born = 2000;
153+
p1->born = 2000;
154+
```
155+
156+
You can consider an array name as a pointer. The difference between an array name and a pointer is that an array can only point to the same memory. An array name can be regarded as a constant pointer.
157+
158+
We print the value of `&students`, `students` and `&students[0]`, it can be found that the three addresses are exactly the same, and are the address of the first element in array `students`.
159+
160+
```C++
161+
//pointer-array.cpp
162+
printf("&students = %p\n", &students);
163+
printf("students = %p\n", students);
164+
printf("&students[0] = %p\n", &students[0]);
165+
```
166+
167+
If we assign an array (the address) to a pointer `p`, then `p` can used in an array style (`p[0]`) to access the elements. `p` is a pointer to a position of the memory and regard that position as the starting address of an object. But `p` does not know how many elements are there. We must be very careful with the out-of-bound error.
168+
169+
```C++
170+
//pointer-array.cpp
171+
Student * p = students;
172+
p[0].born = 2000;
173+
p[1].born = 2001;
174+
p[2].born = 2002;
175+
```
176+
177+
Since the value of a pointer is an address, an integer number, you can perform arithmetic operations on a pointer. But be careful that the address will not increase 1 after you perform `p + 1`. `p + num` or `num + p` points to the *num-th* element of the array `p`. `p - num` points to the *-num-th* element. The address value changes according to the data type. If the data type is `float *`, then the address will increase 4 bytes after `p + 1` or `p++`.
178+
179+
```C++
180+
//arithmetic.cpp
181+
int numbers[4] = {0, 1, 2, 3};
182+
int * p = numbers + 1; // point to the element with value 1
183+
p++; // point to the element with value 2
184+
185+
*p = 20; //change 2 to 20
186+
*(p-1) = 10; //change 1 to 10
187+
p[1] = 30; //change 3 to 30
188+
```
189+
190+
![After the operation and assignments, the pointer and the array should be as shown in the figure.](images/pointer-arithmetic.png)
191+
192+
193+
We do not know how many elements followed the address that a pointer points to, and we also do not know a pointer is from an integer or an integer array. The following code can be compiled successfully, but the memory accessing will be out-of-bound.
194+
195+
```C++
196+
int num = 0;
197+
int * p = &num;
198+
p[-1] = 2; //out of bound
199+
p[0] = 3; //okay
200+
*(p+1) = 4; //out of bound
201+
````
202+
203+
204+
## Allocate memory: C style
205+
206+
## Allocate memory: C++ style
13207
14-
## Common mistakes of using a pointer
15208
16-
* null pointer, random pointer
17-
* out of bound
18-
* memory leak
19209
20210
## Lab
21211

week05/examples/arithmetic.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,15 @@ int main()
1010
int numbers[4] = {0, 1, 2, 3};
1111
PRINT_ARRAY(numbers, 4)
1212

13-
int * p = numbers + 1;
14-
p++;
13+
int * p = numbers + 1; // point to the element with value 1
14+
p++; // point to the element with value 2
1515

1616
cout << "numbers = " << numbers << endl;
1717
cout << "p = " << p << endl;
1818

19-
*p = 20;
20-
*(p-1) = 10;
21-
p[1] = 30;
19+
*p = 20; //change 2 to 20
20+
*(p-1) = 10; //change 1 to 10
21+
p[1] = 30; //change 3 to 30
2222

2323
PRINT_ARRAY(numbers, 4)
2424

week05/examples/const-pointer.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ int main()
1515
int num = 1;
1616
int another = 2;
1717

18-
//You cannot change the value the p1 points to through p1
18+
//You cannot change the value that p1 points to through p1
1919
const int * p1 = &num;
2020
*p1 = 3; //error
2121
num = 3; //okay
@@ -25,8 +25,10 @@ int main()
2525
*p2 = 3; //okay
2626
p2 = &another; //error
2727

28-
//You cannot change either
28+
//You can change neither
2929
const int* const p3 = &num;
30+
*p3 = 3; //error
31+
p3 = &another; // error
3032

3133
return 0;
3234
}

week05/examples/newdelete.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
#include <iostream>
22
using namespace std;
33

4-
struct Student{
4+
struct Student
5+
{
56
char name[4];
67
int born;
78
bool male;

week05/examples/pointer-array.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
#include <iostream>
22
using namespace std;
33

4-
struct Student{
4+
struct Student
5+
{
56
char name[4];
67
int born;
78
bool male;

week05/examples/pointer-struct.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22
#include <cstring>
33
using namespace std;
44

5-
struct Student{
5+
struct Student
6+
{
67
char name[4];
78
int born;
89
bool male;

week05/images/pointer-arithmetic.png

152 KB
Loading
181 KB
Loading

week05/images/pointer-pointer.png

163 KB
Loading

week05/images/pointer-struct.png

201 KB
Loading

week05/images/pointer.png

125 KB
Loading

0 commit comments

Comments
 (0)