一般咱们都晓得像 C/Cpp 这类语言, 须要手动管理内存, 可是一样地也很容易出现内存管理不当引起的问题, 譬如空指针, 野指针之类的东西. 而后就发展出了带 Garbage Collection(垃圾回收) 的语言. 可是 GC 这个玩意最明显的地方就是运行时占用内存比较大, 还有就是回收的时候会停顿. 要是应用对性能敏感的话, 还停顿一下, 有点要命. 或者应用是跑在小内存设备上的.安全
如今咱们要是有一门语言, 又不须要 GC, 还能保证内存安全, 那就赞了. 恰好 Rust 符合要求.bash
00. Rust 内存管理
01. Rust 内存管理 Ownership & Move
02. Rust 内存管理 Copy & Clone(上)
03. Rust 内存管理 Copy & Clone(下)post
通常的 C/Cpp 程序很容易制造内存错误, 譬如这段代码.性能
#include <stdio.h>
#include <string.h>
int main(int argv, char **argc) {
char *str = "hello, world";
strcpy(str, "hello, rust");
printf("%s\n", str);
return 0;
}
复制代码
表面上看不出问题, 直接编译也经过了, 可是一执行就 error
了. 若是要揪其缘由, 咱们先编译以后再经过 objdump 看看.
Section __cstring
在 Segment __TEXT
内
这里会出现错误是由于 __TEXT
是一个可读可执行区域, 可是这段代码想给这个区域写数据, 等于讲没有这方面的权限, 最明显的反应就是进程非正常退出了.ui
$ gcc xxx.c -g -Wall
$ objdump -s a.out
Contents of section __cstring:
100000f90 68656c6c 6f2c2077 6f726c64 0068656c hello, world.hel
100000fa0 6c6f2c20 72757374 0025730a 00 lo, rust.%s..
$ size -x -l -m a.out
Segment __TEXT: 0x1000 (vmaddr 0x100000000 fileoff 0)
Section __text: 0x60 (addr 0x100000f00 offset 3840)
Section __stubs: 0xc (addr 0x100000f60 offset 3936)
Section __stub_helper: 0x24 (addr 0x100000f6c offset 3948)
Section __cstring: 0x1d (addr 0x100000f90 offset 3984)
Section __unwind_info: 0x48 (addr 0x100000fb0 offset 4016)
total 0xf5
复制代码
固然咱们日常开发不会特地这么写. 虽然编译成功了, 可是执行中会发生 Segmentation faultspa
int a = 10;
int *p = &a;
p = NULL;
printf("%d\n", *p);
复制代码
咱们这里给 p 申请了一块内存空间, 而后给里面写了些值, 判断 p 不是 NULL, 把 p 指向的区域给 free 了, 可是 p 仍是指向那块地址, 这时候 p 就是悬空指针了. 最后打印出了 p is not NULL.
假如咱们再使用 p 作一些操做, 极可能访问到受保护的内存, 形成 Segmentation fault设计
#include <stdio.h>
#include <string.h>
int main(int argv, char **argc) {
char *p = NULL;
p = (char *)malloc(50);
strcpy(p, "test");
if (NULL != p) {
free(p);
}
if (NULL != p) {
printf("p is not NULL.");
}
return 0;
}
复制代码
......
有些问题不少能够经过规范来避免, 可是无法保证每一个人遵照规范. 因此 Rust 设计出来就是为了从语言层面解决内存问题.指针
又开坑了, 处处挖坑.code