标签搜索

00. Rust 内存管理

limit
2018-12-09 / 0 评论 / 8 阅读 / 正在检测是否收录...
通常我们都晓得像 C/Cpp 这类语言, 需要手动管理内存, 但是同样地也很容易出现内存管理不当引发的问题, 譬如空指针, 野指针之类的东西. 然后就发展出了带 Garbage Collection(垃圾回收) 的语言. 但是 GC 这个玩意最明显的地方就是运行时占用内存比较大, 还有就是回收的时候会停顿. 要是应用对性能敏感的话, 还停顿一下, 有点要命. 或者应用是跑在小内存设备上的.

现在我们要是有一门语言, 又不需要 GC, 还能保证内存安全, 那就赞了.
刚好 Rust 符合要求.

应该是一个系列的吧

00. Rust 内存管理
01. Rust 内存管理 Ownership & Move
02. Rust 内存管理 Copy & Clone(上)
03. Rust 内存管理 Copy & Clone(下)

常见的内存错误

Segmentation fault

一般的 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 __cstringSegment __TEXT
这里会出现错误是因为 __TEXT是一个可读可执行区域, 但是这段代码想给这个区域写数据, 等于讲没有这方面的权限, 最明显的反应就是进程非正常退出了.

$ 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 fault

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 设计出来就是为了从语言层面解决内存问题.


又开坑了, 到处挖坑.

0

评论 (0)

取消