From: bors Date: Mon, 22 Aug 2016 15:29:41 +0000 (-0700) Subject: Auto merge of #35871 - bluss:cstring-new, r=alexcrichton X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=3c5a0fa45b5e2786b6e64e27f48cd129e7aefdbd;p=rust.git Auto merge of #35871 - bluss:cstring-new, r=alexcrichton cstring: avoid excessive growth just to 0-terminate Based on following what happens in CString::new("string literal"): 1. Using `Into>`, a Vec is allocated with capacity exactly equal to the string's input length. 2. By `v.push(0)`, the Vec is grown to twice capacity, since it was full. 3. By `v.into_boxed_slice()`, the Vec capacity is shrunk to fit the length again. If we use `.reserve_exact(1)` just before the push, then we avoid the capacity doubling that we're going to have to shrink anyway. Growing by just 1 byte means that the step (2) is less likely to have to move the memory to a larger allocation chunk, and that the step (3) does not have to reallocate. Addresses part of #35838 --- 3c5a0fa45b5e2786b6e64e27f48cd129e7aefdbd diff --cc src/libstd/ffi/c_str.rs index 18a7c7c8457,6f217be31fe..5dae1a09bf4 --- a/src/libstd/ffi/c_str.rs +++ b/src/libstd/ffi/c_str.rs @@@ -211,19 -211,9 +211,20 @@@ impl CString /// This method is equivalent to `new` except that no runtime assertion /// is made that `v` contains no 0 bytes, and it requires an actual /// byte vector, not anything that can be converted to one with Into. + /// + /// # Examples + /// + /// ``` + /// use std::ffi::CString; + /// + /// let raw = b"foo".to_vec(); + /// unsafe { + /// let c_string = CString::from_vec_unchecked(raw); + /// } + /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub unsafe fn from_vec_unchecked(mut v: Vec) -> CString { + v.reserve_exact(1); v.push(0); CString { inner: v.into_boxed_slice() } }