about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2016-08-22 08:29:41 -0700
committerGitHub <noreply@github.com>2016-08-22 08:29:41 -0700
commit3c5a0fa45b5e2786b6e64e27f48cd129e7aefdbd (patch)
treeb88c447994c5e59c229de24412151077d60cd285 /src
parent57a1f684cd14d8f042b4356d8c1518ca3e02cecf (diff)
parent876c02cc1ab537703c4d6f19693dd9a42b131442 (diff)
downloadrust-3c5a0fa45b5e2786b6e64e27f48cd129e7aefdbd.tar.gz
rust-3c5a0fa45b5e2786b6e64e27f48cd129e7aefdbd.zip
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<Vec<u8>>`, 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
Diffstat (limited to 'src')
-rw-r--r--src/libstd/ffi/c_str.rs1
1 files changed, 1 insertions, 0 deletions
diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs
index 18a7c7c8457..5dae1a09bf4 100644
--- a/src/libstd/ffi/c_str.rs
+++ b/src/libstd/ffi/c_str.rs
@@ -224,6 +224,7 @@ impl CString {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub unsafe fn from_vec_unchecked(mut v: Vec<u8>) -> CString {
+        v.reserve_exact(1);
         v.push(0);
         CString { inner: v.into_boxed_slice() }
     }