为什么要学Rust编程?内存的问题,C(谁)能体会

当我听到在不远的将来,Linux内核会支持Rust语言的这个消息时,我心潮澎湃,欣喜若狂。作为一名用了十几年C语言Linux开发的员来说,早就体会到了指针带来快乐与痛苦,也享受了C的门槛带来的系统知识的提升和调试诊断经验的积累。每当遇到内存踩踏的问题,总要深深的口气,哎又要被蹂躏几个月了。这么多年来自己倒是也思考和总结了诊断内存问题的方法、技巧,也开发了一些诊断工具。但是这些工具还是不能预防,也不能解决普遍的问题,只能在遇到问题后case by case的分析和应对,为次也付出了漫长的资源和时间。所以说在大型的系统中,C的维护成本极高极高,虽然开发效率也很低。

Rust语言的设计者针对C/C++的痛点,并且博采众高级语言的特长,设计了内存安全的、性能卓越的编程语言。

下面分享下C语言编程中常常遇到的内存相关的问题,及Rust是如何能避免这些问题的。

buffer overflow
char array[4] = {1,2,3,4};
array[4] = 0; //valid indexes are 0, 1,2,3.

简简单单的两行代码,一不小心就会铸成大错。换成Rust,会是什么结果呢?

let mut array:[u32;4] = [1,2,3,4];
array[4] = 0;
//^^^^^^^^ index out of bounds: the len is 4 but the index is 4

Rust编译的时候,会报错out of bounds。 从array的声明可以看到,array不仅仅保存了数据,还包含了数据的类型和数据的个数,因此编译器在编译的时候可以检查出错误。

memory leak
在C语言中,函数在返回前,忘记释放str,会导致内存泄露。

 int fun()
 {
     char *str = strdup("hello world\n"); //alloced memory for string
     printf("%s\n", str);
     return 0;                            //missed to free memory
 }

在Rust语言中,str的作用域在“}”结束后,然后会被自动drop。

 fn fun(){
     let str = String::from("hello world");
 }  
double free

在内核编程时经常会遇到类似的情况:

(1) Slab为程序分配了100字节内存,假设地址为0xc000 1000;

(2) 函数退出时,释放了0xc000 1000这个地址。

(3)case1 :在2-3之间,如果函数被中断或者调度;然后其他程序被分配了0xc000 1000这一片区域的内存。程序再次释放0xc000 1000这块内存,会导致其他程序运行出错。case 2: 重复释放同一块内存,Slab会报错。

   1 int handle_data()
   2 {
   3     char *data = kalloc(100, GFP_KERNEL);14     char *p = data;
   5 
   6     //...
   7 
   8 exit:
   9     if (data)
  10         free(data);211 
  12     if (p)313         free(p);
  14 }

在rust中,内存的owner只有一个,指针的赋值叫做转移,新指针或者ownership,老指针失效。新指针离开作用域时会自动释放内存。不会有double free的问题。

use after free
在C语言里,指针就是地址,是地址就可以操作,管你释放了没有。而Rust有作用域和生命周期的概念, game over了就不能用,你用的话就编不过。

wild pointer
在C语言里,野指针是最烦人的,没有之一。而在Rust语言里面,这都不是事。

Null pointer
在C中,有很多的代码是做空指针的检查的,尽管如此,很大一部分的crash都是有NULL指针导致的。我一直在问自己,难道gcc不能加个空指针的检查吗? 在Rust中,压根没有空指针,哈哈哈。有option,而且编译器管的很宽,保证你的代码处理了所有的option。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值