Skip to content

Commit 00bd306

Browse files
committed
Extend documentation for mem uninit to discuss partial allocation of the values
1 parent 96d1334 commit 00bd306

File tree

1 file changed

+42
-0
lines changed

1 file changed

+42
-0
lines changed

src/libcore/mem.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -530,6 +530,12 @@ pub unsafe fn zeroed<T>() -> T {
530530
/// it goes out of scope (and therefore would be dropped). Note that this
531531
/// includes a `panic` occurring and unwinding the stack suddenly.
532532
///
533+
/// If you partially initialize an array, you may need to use
534+
/// [`ptr::drop_in_place`][drop_in_place] to remove the set you have created
535+
/// followed by [`mem::forget`][mem_forget] to prevent drop running on the
536+
/// array. If a partially allocated array is dropped this may lead to
537+
/// undefined behaviour.
538+
///
533539
/// # Examples
534540
///
535541
/// Here's how to safely initialize an array of [`Vec`]s.
@@ -583,11 +589,47 @@ pub unsafe fn zeroed<T>() -> T {
583589
/// println!("{:?}", &data[0]);
584590
/// ```
585591
///
592+
/// This example shows how to handle partially allocated arrays, which could
593+
/// be found in low-level datastructures.
594+
///
595+
/// ```
596+
/// use std::mem;
597+
/// use std::ptr;
598+
///
599+
/// // Count the number of elements we have assigned.
600+
/// let mut data_len: usize = 0;
601+
/// let mut data: [String; 1000];
602+
///
603+
/// unsafe {
604+
/// data = mem::uninitialized();
605+
///
606+
/// for elem in &mut data[0..500] {
607+
/// ptr::write(elem, String::from("hello"));
608+
/// data_len += 1;
609+
/// }
610+
///
611+
/// // For each item in the array, drop if we allocated it.
612+
/// for i in &mut data[0..data_len] {
613+
/// ptr::drop_in_place(i);
614+
/// }
615+
/// }
616+
/// // Forget the data. If this is allowed to drop, you may see a crash such as:
617+
/// // 'mem_uninit_test(2457,0x7fffb55dd380) malloc: *** error for object 0x7ff3b8402920: pointer being freed was not allocated'
618+
/// mem::forget(data);
619+
/// ```
620+
///
621+
/// An alternate strategy is to use [`mem::zeroed`][mem_zeroed] with ptr
622+
/// comparison. This is a very error prone strategy and may only be relevant
623+
/// for FFI.
624+
///
586625
/// [`Vec`]: ../../std/vec/struct.Vec.html
587626
/// [`vec!`]: ../../std/macro.vec.html
588627
/// [`Clone`]: ../../std/clone/trait.Clone.html
589628
/// [ub]: ../../reference/behavior-considered-undefined.html
590629
/// [write]: ../ptr/fn.write.html
630+
/// [drop_in_place]: ../ptr/fn.drop_in_place.html
631+
/// [mem_zeroed]: fn.zeroed.html
632+
/// [mem_forget]: fn.forget.html
591633
/// [copy]: ../intrinsics/fn.copy.html
592634
/// [copy_no]: ../intrinsics/fn.copy_nonoverlapping.html
593635
/// [`Drop`]: ../ops/trait.Drop.html

0 commit comments

Comments
 (0)