在Rust中指针使用(rust 指令)

起因

今天学习一下Rust中的指针.

原生指针

//原生指针 *const (不可变) 和 *mut(可变)
let mut x = 32;
let  y = &mut x; //引用
unsafe {
    *y =64;  //通过原生指针 修改值
}

引用

//引用  通过&和&mut
let a = 100;
let b = &a;
println!("a={}", b);

智能指针

智能指针最早在c++得到了应用.智能指针是RAII(资源获取即初始化)和作用域范围的完美结合,在离开所在作用域的范围的进行资源的释放.

#ifndef ALGORITHM_MYCLASS_H
#define ALGORITHM_MYCLASS_H

#include <iostream>
using namespace  std;

class MyClass
{
public:
    char* p;
    MyClass()
    {
        cout << "调用构造函数" << endl;
        p = new char[1024 * 1024 * 100]();  //在堆上分配100m的空间
    }

    ~MyClass()              
    {
        cout << "调用析构函数" << endl;
        delete[] p;                       //在析构函数时,释放100m空间
    }
};


#endif //ALGORITHM_MYCLASS_H
int main(int argc, char *argv[]) {

    {
        vector<int> vec1{1, 2, 3};    //①在任务管理器中看当前程序所占内存大小
        unique_ptr<MyClass> myClass(new MyClass());  //unique_ptr 智能指针 在离开所在的作用域,自动释放资源
        vector<int> vec2{1, 2, 3};    //②在任务管理器中看当前程序所占内存大小
    }

    cin.get();                        //③任务管理器中看当前程序所占内存大小,
    //得出结论: 通过智能指针给myClass在堆上进行内存分配,在离开所在的作用域后,自动调用析构函数,并释放资源
    return 0;
}

进入正题,Rust中最典型的智能指针非Box和String莫属,String使用最多,Rust中的智能指针都会实现Drop(没实现Drop,不会自动释放资源,能叫智能)和Deref(没有*,能叫指针),在Rust中类型默认是分配栈上的,可以通过Box(有点像C#的装箱操作,在IL中使用box进行装箱操作)分配到堆上.具体看下面的示例代码:

#[derive(Debug)]
struct MyPoint
{
    x:i32,
    y:i32,
}

//这里只是打印是否调用drop
impl Drop for MyPoint {
    fn drop(&mut self) {
        println!("drop MyPoint x={} y={}", self.x,self.y);
    }
}

fn main() {
    {
        let p1 = MyPoint { x: 1 };  //是在栈上进行的内存分配
        
      {
        	let point = Box::new(MyPoint { x: 1 });  //通过Box的new函数在堆上开辟内存空间
          println!("MyPoint x={}",a.x);
        }
        //Box实现Drop trait在离开所在作用域自动内存
    }
}

Box<T>源码,只有new/drop/deref.

/// A pointer type for heap allocation.
///
/// See the [module-level documentation](../../std/boxed/index.html) for more.
#[lang = "owned_box"]  //编译器实现内存分配和释放 由于实现drop trait可以自动释放资源
#[fundamental]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Box<T: ?Sized>(Unique<T>);

impl<T> Box<T> {
    /// Allocates memory on the heap and then places `x` into it.
    #[stable(feature = "rust1", since = "1.0.0")]
    #[inline(always)]
    pub fn new(x: T) -> Box<T> {
        box x  //box 在编译时,由编译器将box替换为exchange_malloc在离开作用域的是调用drop
    }
}


#[stable(feature = "rust1", since = "1.0.0")]
unsafe impl<#[may_dangle] T: ?Sized> Drop for Box<T> {
    fn drop(&mut self) {
        // FIXME: Do nothing, drop is currently performed by compiler.
        //由编译器生成 释放资源代码
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: ?Sized> Deref for Box<T> {
    type Target = T;

    fn deref(&self) -> &T {
        &**self
    }
}

通过Rust编译器rustc,生成汇编代码,是可以看到exchange_malloc函数的,具体看下边生成的代码:

//通过--emit 可以指定 asm(汇编) llvm-ir(llvm中间代码) obj(目标文件)
rustc --emit asm  .\test.rs

个人能力有限,如果您发现有什么不对,请私信我

如果您觉得对您有用的话,可以点个赞或者加个关注,欢迎大家一起进行技术交流

原文链接:,转发请注明来源!