File tree Expand file tree Collapse file tree 1 file changed +33
-1
lines changed Expand file tree Collapse file tree 1 file changed +33
-1
lines changed Original file line number Diff line number Diff line change @@ -20,6 +20,17 @@ summary: 内存管理
20
20
这些变量所在的内存称为` ”堆“(heap) ` ,` ”堆“所在的内存是用户手动管理的 ` 。
21
21
22
22
23
+ ## 栈内存 vs 堆内存
24
+ C/C++ 中有两种主要的内存分配方式:栈内存和堆内存。
25
+
26
+ - 栈内存:当你在函数中声明局部变量时,编译器会自动在栈上为这些变量分配内存。这种分配是自动的,且非常高效,因为栈内存的分配和释放是由编译器管理的,分配和释放的时间非常短(通过调整栈指针)。然而,栈内存有以下限制:
27
+
28
+ 1 . 栈的大小是有限的,通常只有几 MB。因此,不能在栈上分配大量内存。
29
+ 2 . 栈上的变量的生命周期是有限的,它们在函数结束时自动销毁,无法跨函数使用。
30
+
31
+ - 堆内存:堆内存是程序运行时的动态内存,程序员可以通过 malloc/free 或 new/delete 来手动管理堆内存。堆内存的优点是可以分配更大的内存块,且内存的生命周期由程序员控制。缺点是堆内存的分配和释放速度比栈慢,且需要程序员手动管理内存,防止内存泄漏。
32
+
33
+
23
34
# void指针
24
35
前面章节已经说过了,每一块内存都有地址,通过指针变量可以获取指定地址的内存块。
25
36
` 指针变量必须有类型,否则编译器无法知道,如何解读内存块保存的二进制数据。 `
@@ -47,4 +58,25 @@ void* p = &a;
47
58
48
59
printf ("%c\n", * p); // 报错
49
60
```
50
- 上面示例中,p是一个 void 指针,所以这时无法用*p取出指针指向的值。
61
+ 上面示例中,p是一个 void 指针,所以这时无法用*p取出指针指向的值。
62
+
63
+
64
+
65
+ # restrict 说明符
66
+ 声明指针变量时,可以使用restrict说明符,告诉编译器,该块内存区域只有当前指针一种访问方式,其他指针不能读写该块内存。这种指针称为`“受限指针”(restrict pointer)`。
67
+
68
+ ```C
69
+ int* restrict p;
70
+ p = malloc(sizeof(int));
71
+ ```
72
+ 上面示例中,声明指针变量p时,加入了restrict说明符,使得p变成了受限指针。
73
+ 后面,当p指向malloc()函数返回的一块内存区域,就意味着,该区域只有通过p来访问,不存在其他访问方式。
74
+
75
+ ``` C
76
+ int * restrict p;
77
+ p = malloc(sizeof (int ));
78
+
79
+ int * q = p;
80
+ *q = 0 ; // 未定义行为
81
+ ```
82
+ 上面示例中,另一个指针q与受限指针p指向同一块内存,现在该内存有p和q两种访问方式。这就违反了对编译器的承诺,后面通过* q对该内存区域赋值,会导致未定义行为。
You can’t perform that action at this time.
0 commit comments