@@ -738,53 +738,88 @@ impl<T> Vec<T> {
738
738
self
739
739
}
740
740
741
- /// Sets the length of a vector.
741
+ /// Forces the length of the vector to `new_len` .
742
742
///
743
- /// This will explicitly set the size of the vector, without actually
744
- /// modifying its buffers, so it is up to the caller to ensure that the
745
- /// vector is actually the specified size.
743
+ /// This is a low-level operation that maintains none of the normal
744
+ /// invariants of the type. Normally changing the length of a vector
745
+ /// is done using one of the safe operations instead, such as
746
+ /// [`truncate`], [`resize`], [`extend`], or [`clear`].
746
747
///
747
- /// # Examples
748
+ /// [`truncate`]: #method.truncate
749
+ /// [`resize`]: #method.resize
750
+ /// [`extend`]: #method.extend-1
751
+ /// [`clear`]: #method.clear
748
752
///
749
- /// ```
750
- /// use std::ptr;
753
+ /// # Safety
751
754
///
752
- /// let mut vec = vec!['r', 'u', 's', 't'];
755
+ /// - `new_len` must be less than or equal to [`capacity()`].
756
+ /// - The elements at `old_len..new_len` must be initialized.
753
757
///
754
- /// unsafe {
755
- /// ptr::drop_in_place(&mut vec[3]);
756
- /// vec.set_len(3);
758
+ /// [`capacity()`]: #method.capacity
759
+ ///
760
+ /// # Examples
761
+ ///
762
+ /// This method can be useful for situations in which the vector
763
+ /// is serving as a buffer for other code, particularly over FFI:
764
+ ///
765
+ /// ```no_run
766
+ /// # #![allow(dead_code)]
767
+ /// # // This is just a minimal skeleton for the doc example;
768
+ /// # // don't use this as a starting point for a real library.
769
+ /// # pub struct StreamWrapper { strm: *mut std::ffi::c_void }
770
+ /// # const Z_OK: i32 = 0;
771
+ /// # extern "C" {
772
+ /// # fn deflateGetDictionary(
773
+ /// # strm: *mut std::ffi::c_void,
774
+ /// # dictionary: *mut u8,
775
+ /// # dictLength: *mut usize,
776
+ /// # ) -> i32;
777
+ /// # }
778
+ /// # impl StreamWrapper {
779
+ /// pub fn get_dictionary(&self) -> Option<Vec<u8>> {
780
+ /// // Per the FFI method's docs, "32768 bytes is always enough".
781
+ /// let mut dict = Vec::with_capacity(32_768);
782
+ /// let mut dict_length = 0;
783
+ /// // SAFETY: When `deflateGetDictionary` returns `Z_OK`, it holds that:
784
+ /// // 1. `dict_length` elements were initialized.
785
+ /// // 2. `dict_length` <= the capacity (32_768)
786
+ /// // which makes `set_len` safe to call.
787
+ /// unsafe {
788
+ /// // Make the FFI call...
789
+ /// let r = deflateGetDictionary(self.strm, dict.as_mut_ptr(), &mut dict_length);
790
+ /// if r == Z_OK {
791
+ /// // ...and update the length to what was initialized.
792
+ /// dict.set_len(dict_length);
793
+ /// Some(dict)
794
+ /// } else {
795
+ /// None
796
+ /// }
797
+ /// }
757
798
/// }
758
- /// assert_eq!(vec, ['r', 'u', 's']);
799
+ /// # }
759
800
/// ```
760
801
///
761
- /// In this example, there is a memory leak since the memory locations
762
- /// owned by the inner vectors were not freed prior to the `set_len` call:
802
+ /// While the following example is sound , there is a memory leak since
803
+ /// the inner vectors were not freed prior to the `set_len` call:
763
804
///
764
805
/// ```
765
806
/// let mut vec = vec![vec![1, 0, 0],
766
807
/// vec![0, 1, 0],
767
808
/// vec![0, 0, 1]];
809
+ /// // SAFETY:
810
+ /// // 1. `old_len..0` is empty so no elements need to be initialized.
811
+ /// // 2. `0 <= capacity` always holds whatever `capacity` is.
768
812
/// unsafe {
769
813
/// vec.set_len(0);
770
814
/// }
771
815
/// ```
772
816
///
773
- /// In this example, the vector gets expanded from zero to four items
774
- /// without any memory allocations occurring, resulting in vector
775
- /// values of unallocated memory:
776
- ///
777
- /// ```
778
- /// let mut vec: Vec<char> = Vec::new();
779
- ///
780
- /// unsafe {
781
- /// vec.set_len(4);
782
- /// }
783
- /// ```
817
+ /// Normally, here, one would use [`clear`] instead to correctly drop
818
+ /// the contents and thus not leak memory.
784
819
#[ inline]
785
820
#[ stable( feature = "rust1" , since = "1.0.0" ) ]
786
- pub unsafe fn set_len ( & mut self , len : usize ) {
787
- self . len = len ;
821
+ pub unsafe fn set_len ( & mut self , new_len : usize ) {
822
+ self . len = new_len ;
788
823
}
789
824
790
825
/// Removes an element from the vector and returns it.
0 commit comments