Skip to content

Commit 02b7b00

Browse files
committed
docs: add pointer learning
1 parent d882568 commit 02b7b00

File tree

1 file changed

+179
-1
lines changed

1 file changed

+179
-1
lines changed

content/blog/learn-cpp/index.md

Lines changed: 179 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ tags: ["C++", "算法"]
77

88
## 起因
99

10-
大概是 603 分考进了福专的给排水,所以考虑转专业了,但是大一转专业考高数干不过别人,所以决定大二靠机试转,然后顺便学学算法和 C++。
10+
大概是 604 分考进了福专的给排水,所以考虑转专业了,但是大一转专业考高数干不过别人,所以决定大二靠机试转,然后顺便学学算法和 C++。
1111

1212
## 为什么是从 0.1?
1313

@@ -49,3 +49,181 @@ int main()
4949
lePetitPrince->author.c_str());
5050
}
5151
```
52+
53+
### 指针
54+
55+
#### 指针基础
56+
57+
```cpp
58+
#include <iostream>
59+
#include <cstring>
60+
61+
using namespace std;
62+
63+
struct Book
64+
{
65+
int id;
66+
string name;
67+
};
68+
69+
int main()
70+
{
71+
// 在堆上分配Book的内存,并且返回Book实例的指针
72+
auto book = new Book{1, "BookA"};
73+
74+
// 使用->访问结构体指针的字段
75+
cout << book->id << "\n";
76+
77+
// 必须手动释放,否则会造成内存泄漏
78+
delete book;
79+
80+
size_t size = 10;
81+
82+
// 在堆上分配int数组的内存,长度为size
83+
auto numbers = new int[size];
84+
85+
// 使用memset分配统一初始值
86+
memset(numbers, 0, size * sizeof(int));
87+
88+
// 遍历指针数组
89+
for (auto i = 0; i < size; i++)
90+
{
91+
cout << numbers[i] << "\n";
92+
}
93+
94+
// 手动释放指针数组
95+
delete[] numbers;
96+
}
97+
```
98+
99+
#### 普通指针风险
100+
101+
- 内存泄漏
102+
103+
```cpp
104+
void foo(){
105+
// 在堆上分配Book的内存,并且返回Book实例的指针
106+
auto book = new Book{1, "Book"};
107+
108+
// 模拟运行时抛出异常
109+
throw runtime_error("A unususal error ~");
110+
111+
// 抛出异常后分配在堆上的Book实例无法被清理,造成内存泄漏
112+
delete book;
113+
}
114+
```
115+
116+
- 野指针
117+
118+
```cpp
119+
void foo(){
120+
auto book = new Book{1, "Book"};
121+
122+
// 释放book内存,book变成野指针(悬空指针)
123+
delete book;
124+
125+
// 访问野指针,发生神秘行为
126+
cout << book->id << "\n";
127+
}
128+
```
129+
130+
- 多次释放内存
131+
132+
```cpp
133+
void foo(){
134+
auto book = new Book{1, "Book"};
135+
136+
// 释放book内存
137+
delete book;
138+
139+
// Booooooom!
140+
delete book;
141+
}
142+
```
143+
144+
#### 智能指针
145+
146+
规避上述指针风险的最好方法就是不要使用new/delete管理内存,智能指针就是一个很好的选择
147+
148+
```cpp
149+
#include <iostream>
150+
#include <memory>
151+
152+
using namespace std;
153+
154+
struct Book
155+
{
156+
int id;
157+
string name;
158+
159+
// 添加构造函数
160+
Book(int i, const string &n) : id(i), name(n) {}
161+
};
162+
163+
int main()
164+
{
165+
// 使用智能指针创建Book指针
166+
auto book = make_unique<Book>(1, "BookA");
167+
168+
// 使用->访问结构体指针的字段
169+
cout << book->id << "\n";
170+
171+
// 无需手动释放,自动管理
172+
173+
size_t size = 10;
174+
175+
// 使用智能指针创建int数组指针
176+
auto numbers = make_unique<int[]>(size);
177+
178+
// 遍历指针数组初始化
179+
for (auto i = 0; i < size; i++)
180+
{
181+
numbers[i] = 0;
182+
}
183+
184+
// 遍历指针数组
185+
for (auto i = 0; i < size; i++)
186+
{
187+
cout << numbers[i] << "\n";
188+
}
189+
190+
// 无需手动释放,自动管理
191+
}
192+
```
193+
194+
#### 函数指针
195+
196+
```cpp
197+
#include <iostream>
198+
#include <cstring>
199+
200+
using namespace std;
201+
202+
int add(int x, int y)
203+
{
204+
return x + y;
205+
}
206+
207+
int subtract(int x, int y)
208+
{
209+
return x - y;
210+
}
211+
212+
int main()
213+
{
214+
// 方法指针 返回类型 (*指针变量名)(参数,...)
215+
int (*operate)(int, int);
216+
217+
int type = 1;
218+
switch (type)
219+
{
220+
case 1:
221+
operate = add;
222+
break;/
223+
case 2:
224+
operate = subtract;
225+
break;
226+
}
227+
cout << operate(114, 514) << "\n";
228+
}
229+
```

0 commit comments

Comments
 (0)