返回

Rust 数据结构之动态数组 Vec 的实战

前端

前言

Rust 作为一门注重内存安全和性能的系统编程语言,提供了强大的数据结构库。其中,Vec 是 Rust 中用于存储和管理动态数组的标准库数据结构。它与其他语言中内置的动态数组类似,但 Rust 的内存管理机制赋予了 Vec 独特的特性。本文将通过动手实现 Vec,带领读者深入理解 Rust 的内存管理机制和动态数组的原理。

Vec 的底层实现

Vec 的底层实现依赖于以下几个关键概念:

  • 指针 :Vec 使用指针来指向底层存储数据的内存块。
  • 容量 :Vec 的容量表示其可以容纳元素的最大数量。
  • 长度 :Vec 的长度表示当前存储的元素数量。
  • Drop 机制 :Rust 的 Drop 机制确保在 Vec 不再被使用时释放其占用的内存。

动手实现 Vec

让我们动手实现一个简化的 Vec 数据结构:

struct Vec<T> {
    ptr: *mut T, // 指向底层存储数据的指针
    cap: usize, // 容量
    len: usize, // 长度
}

impl<T> Vec<T> {
    fn new() -> Self {
        Self {
            ptr: std::ptr::null_mut(), // 初始化为 null 指针
            cap: 0,
            len: 0,
        }
    }

    fn push(&mut self, val: T) {
        if self.len == self.cap {
            self.realloc();
        }
        unsafe {
            *self.ptr.offset(self.len as isize) = val;
        }
        self.len += 1;
    }

    // 省略其他方法...
}

impl<T> Drop for Vec<T> {
    fn drop(&mut self) {
        unsafe {
            std::ptr::drop_in_place(self.ptr);
        }
        std::ptr::free(self.ptr as *mut u8);
    }
}

分析实现

在这个简化实现中:

  • 构造函数 :创建了一个新的 Vec,初始化其指针、容量和长度。
  • push 方法 :添加一个元素到 Vec 中。如果容量已满,则会重新分配内存。
  • Drop 方法 :在 Vec 不再被使用时释放其占用的内存。

理解内存管理

Rust 的内存管理机制确保了 Vec 的内存安全。当 Vec 不再被使用时,Drop 机制会自动调用 Drop 方法释放其占用的内存。指针的使用使 Vec 能够高效地管理内存,而 Drop 机制则确保了内存不会被泄漏。

总结

通过动手实现 Vec 数据结构,我们深入理解了 Rust 的内存管理机制和动态数组的原理。我们探讨了指针、容量、长度和 Drop 机制的概念,并通过代码示例展示了 Vec 的实际使用。这有助于我们更好地理解 Rust 的内存安全特性,并为更复杂的数据结构的实现奠定基础。