关于vector:具有预定义容量的Vec上set_len操作的安全性

Safety of set_len operation on Vec, with predefined capacity

在已声明容量的Vec上调用set_len是否安全?像这样:

1
2
3
4
5
let vec = unsafe {
    let temp = Vec::with_capacity(N);
    temp.set_len(N);
    temp
}

在添加任何元素之前,我的Vector的大小必须为N。

查看文档:

  • https://doc.rust-lang.org/collections/vec/struct.Vec.html#capacity-and-reallocation
  • https://doc.rust-lang.org/collections/vec/struct.Vec.html#method.with_capacity
  • https://doc.rust-lang.org/collections/vec/struct.Vec.html#method.set_len

我有点困惑。 Docs说with_capacity不会改变长度,而set_len说调用者必须确保vector具有适当的长度。这样安全吗?

我需要这个的原因是因为我正在寻找一种声明大小为N的可变缓冲区(&mut [T])的方法,而Vec似乎最合适。我只是想避免让我的类型实现vec![0;n]会带来的Clone。


文档只是模棱两可。措辞可能更好。您的代码示例与以下等效的堆栈一样为" safe ":

1
let mut arr: [T; N] = mem::uninitialized();

这意味着只要您在读取数组之前写入数组的元素就可以了。如果您在写作之前先阅读,则可能会打开鼻恶魔和内存不安全的大门。

I just wanted to avoid clone that vec![0;n] would bring.

llvm会将其优化为单个内存集。


如果通过"我的Vector大小必须为N "表示您需要为10个元素分配内存,则with_capacity已经在执行此操作。

如果您想使用长度为10的向量(虽然不确定为什么,则...),则需要使用初始值对其进行初始化。
即:

1
2
3
4
5
6
let mut temp: Vec<i32> = Vec::with_capacity(10); // allocate room in memory for
                                            // 10 elements. The vector has
                                            // initial capacity 10, length will be the
                                            // number of elements you push into it
                                            // (initially 0)
v.push(1); // now length is 1, capacity still 10

vs

1
2
3
4
5
6
7
let mut v: Vec<i32> = vec![0; 10]; // create a vector with 10 elements
                                   // initialized to 0. You can mutate
                                   // those in place later.
                                   // At this point, length = capacity = 10

v[0] = 1; // mutating first element to 1.
          // length and capacity are both still 10