Skip to content

Commit 0d42398

Browse files
author
Yanbin Zhu
committed
feat(*): c语言内存管理
1 parent e76cf27 commit 0d42398

File tree

1 file changed

+33
-1
lines changed

1 file changed

+33
-1
lines changed

data/blog/c语言/内存管理.mdx

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,17 @@ summary: 内存管理
2020
这些变量所在的内存称为`”堆“(heap)``”堆“所在的内存是用户手动管理的`
2121

2222

23+
## 栈内存 vs 堆内存
24+
C/C++ 中有两种主要的内存分配方式:栈内存和堆内存。
25+
26+
- 栈内存:当你在函数中声明局部变量时,编译器会自动在栈上为这些变量分配内存。这种分配是自动的,且非常高效,因为栈内存的分配和释放是由编译器管理的,分配和释放的时间非常短(通过调整栈指针)。然而,栈内存有以下限制:
27+
28+
1. 栈的大小是有限的,通常只有几 MB。因此,不能在栈上分配大量内存。
29+
2. 栈上的变量的生命周期是有限的,它们在函数结束时自动销毁,无法跨函数使用。
30+
31+
- 堆内存:堆内存是程序运行时的动态内存,程序员可以通过 malloc/free 或 new/delete 来手动管理堆内存。堆内存的优点是可以分配更大的内存块,且内存的生命周期由程序员控制。缺点是堆内存的分配和释放速度比栈慢,且需要程序员手动管理内存,防止内存泄漏。
32+
33+
2334
# void指针
2435
前面章节已经说过了,每一块内存都有地址,通过指针变量可以获取指定地址的内存块。
2536
`指针变量必须有类型,否则编译器无法知道,如何解读内存块保存的二进制数据。`
@@ -47,4 +58,25 @@ void* p = &a;
4758

4859
printf("%c\n", *p); // 报错
4960
```
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对该内存区域赋值,会导致未定义行为。

0 commit comments

Comments
 (0)