Daniel Fath
Daniel Fath

Reputation: 18109

Safety of set_len operation on Vec, with predefined capacity

Is it safe to call set_len on Vec that has declared capacity? Like this:

let vec = unsafe {
    let temp = Vec::with_capacity(N);
    temp.set_len(N);
    temp
}

I need my Vector to be of size N before any elements are to be added.

Looking at docs:

I'm a bit confused. Docs say that with_capacity doesn't change length and set_len says that caller must insure vector has proper length. So is this safe?

The reason I need this is because I was looking for a way to declare a mutable buffer (&mut [T]) of size N and Vec seems to fit the bill the best. I just wanted to avoid having my types implement Clone that vec![0;n] would bring.

Upvotes: 3

Views: 1708

Answers (2)

oli_obk
oli_obk

Reputation: 31263

The docs are just a little ambiguously stated. The wording could be better. Your code example is as "safe" as the following stack-equivalent:

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

Which means that as long as you write to an element of the array before reading it you are fine. If you read before writing, you open the door to nasal demons and memory unsafety.

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

llvm will optimize this to a single memset.

Upvotes: 6

Paolo Falabella
Paolo Falabella

Reputation: 25844

If by "I need my Vector to be of size N" you mean you need memory to be allocated for 10 elements, with_capacity is already doing that.

If you mean you want to have a vector with length 10 (not sure why you would, though...) you need to initialize it with an initial value. i.e.:

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

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

Upvotes: 1

Related Questions