Skip to content

Commit

Permalink
feat(*): c语言内存管理
Browse files Browse the repository at this point in the history
  • Loading branch information
Yanbin Zhu committed Oct 1, 2024
1 parent e76cf27 commit 0d42398
Showing 1 changed file with 33 additions and 1 deletion.
34 changes: 33 additions & 1 deletion data/blog/c语言/内存管理.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,17 @@ summary: 内存管理
这些变量所在的内存称为`”堆“(heap)``”堆“所在的内存是用户手动管理的`


## 栈内存 vs 堆内存
C/C++ 中有两种主要的内存分配方式:栈内存和堆内存。

- 栈内存:当你在函数中声明局部变量时,编译器会自动在栈上为这些变量分配内存。这种分配是自动的,且非常高效,因为栈内存的分配和释放是由编译器管理的,分配和释放的时间非常短(通过调整栈指针)。然而,栈内存有以下限制:

1. 栈的大小是有限的,通常只有几 MB。因此,不能在栈上分配大量内存。
2. 栈上的变量的生命周期是有限的,它们在函数结束时自动销毁,无法跨函数使用。

- 堆内存:堆内存是程序运行时的动态内存,程序员可以通过 malloc/free 或 new/delete 来手动管理堆内存。堆内存的优点是可以分配更大的内存块,且内存的生命周期由程序员控制。缺点是堆内存的分配和释放速度比栈慢,且需要程序员手动管理内存,防止内存泄漏。


# void指针
前面章节已经说过了,每一块内存都有地址,通过指针变量可以获取指定地址的内存块。
`指针变量必须有类型,否则编译器无法知道,如何解读内存块保存的二进制数据。`
Expand Down Expand Up @@ -47,4 +58,25 @@ void* p = &a;

printf("%c\n", *p); // 报错
```
上面示例中,p是一个 void 指针,所以这时无法用*p取出指针指向的值。
上面示例中,p是一个 void 指针,所以这时无法用*p取出指针指向的值。
# restrict 说明符
声明指针变量时,可以使用restrict说明符,告诉编译器,该块内存区域只有当前指针一种访问方式,其他指针不能读写该块内存。这种指针称为`“受限指针”(restrict pointer)`。
```C
int* restrict p;
p = malloc(sizeof(int));
```
上面示例中,声明指针变量p时,加入了restrict说明符,使得p变成了受限指针。
后面,当p指向malloc()函数返回的一块内存区域,就意味着,该区域只有通过p来访问,不存在其他访问方式。

```C
int* restrict p;
p = malloc(sizeof(int));

int* q = p;
*q = 0; // 未定义行为
```
上面示例中,另一个指针q与受限指针p指向同一块内存,现在该内存有p和q两种访问方式。这就违反了对编译器的承诺,后面通过*q对该内存区域赋值,会导致未定义行为。

0 comments on commit 0d42398

Please sign in to comment.