44//! heap allocation in Rust. Boxes provide ownership for this allocation, and
55//! drop their contents when they go out of scope.
66//!
7- //! For non-zero-sized values, a [`Box`] will use the [`Global`] allocator for
8- //! its allocation. It is valid to convert both ways between a [`Box`] and a
9- //! raw pointer allocated with the [`Global`] allocator, given that the
10- //! [`Layout`] used with the allocator is correct for the type. More precisely,
11- //! a `value: *mut T` that has been allocated with the [`Global`] allocator
12- //! with `Layout::for_value(&*value)` may be converted into a box using
13- //! `Box::<T>::from_raw(value)`. Conversely, the memory backing a `value: *mut
14- //! T` obtained from `Box::<T>::into_raw` may be deallocated using the
15- //! [`Global`] allocator with `Layout::for_value(&*value)`.
16- //!
177//! # Examples
188//!
199//! Move a value from the stack to the heap by creating a [`Box`]:
6151//! for a `Cons`. By introducing a `Box`, which has a defined size, we know how
6252//! big `Cons` needs to be.
6353//!
54+ //! # Memory layout
55+ //!
56+ //! For non-zero-sized values, a [`Box`] will use the [`Global`] allocator for
57+ //! its allocation. It is valid to convert both ways between a [`Box`] and a
58+ //! raw pointer allocated with the [`Global`] allocator, given that the
59+ //! [`Layout`] used with the allocator is correct for the type. More precisely,
60+ //! a `value: *mut T` that has been allocated with the [`Global`] allocator
61+ //! with `Layout::for_value(&*value)` may be converted into a box using
62+ //! `Box::<T>::from_raw(value)`. Conversely, the memory backing a `value: *mut
63+ //! T` obtained from `Box::<T>::into_raw` may be deallocated using the
64+ //! [`Global`] allocator with `Layout::for_value(&*value)`.
65+ //!
66+ //!
6467//! [dereferencing]: ../../std/ops/trait.Deref.html
6568//! [`Box`]: struct.Box.html
6669//! [`Global`]: ../alloc/struct.Global.html
@@ -127,24 +130,38 @@ impl<T: ?Sized> Box<T> {
127130 ///
128131 /// After calling this function, the raw pointer is owned by the
129132 /// resulting `Box`. Specifically, the `Box` destructor will call
130- /// the destructor of `T` and free the allocated memory. Since the
131- /// way `Box` allocates and releases memory is unspecified, the
132- /// only valid pointer to pass to this function is the one taken
133- /// from another `Box` via the [`Box::into_raw`] function.
133+ /// the destructor of `T` and free the allocated memory. For this
134+ /// to be safe, the memory must have been allocated in accordance
135+ /// with the [memory layout] used by `Box` .
136+ ///
137+ /// # Safety
134138 ///
135139 /// This function is unsafe because improper use may lead to
136140 /// memory problems. For example, a double-free may occur if the
137141 /// function is called twice on the same raw pointer.
138142 ///
139- /// [`Box::into_raw`]: struct.Box.html#method.into_raw
140- ///
141143 /// # Examples
142- ///
144+ /// Recreate a `Box` which was previously converted to a raw pointer
145+ /// using [`Box::into_raw`]:
143146 /// ```
144147 /// let x = Box::new(5);
145148 /// let ptr = Box::into_raw(x);
146149 /// let x = unsafe { Box::from_raw(ptr) };
147150 /// ```
151+ /// Manually create a `Box` from scratch by using the global allocator:
152+ /// ```
153+ /// use std::alloc::{alloc, Layout};
154+ ///
155+ /// unsafe {
156+ /// let ptr = alloc(Layout::new::<i32>()) as *mut i32;
157+ /// *ptr = 5;
158+ /// let x = Box::from_raw(ptr);
159+ /// }
160+ /// ```
161+ ///
162+ /// [memory layout]: index.html#memory-layout
163+ /// [`Layout`]: ../alloc/struct.Layout.html
164+ /// [`Box::into_raw`]: struct.Box.html#method.into_raw
148165 #[ stable( feature = "box_raw" , since = "1.4.0" ) ]
149166 #[ inline]
150167 pub unsafe fn from_raw ( raw : * mut T ) -> Self {
@@ -157,22 +174,40 @@ impl<T: ?Sized> Box<T> {
157174 ///
158175 /// After calling this function, the caller is responsible for the
159176 /// memory previously managed by the `Box`. In particular, the
160- /// caller should properly destroy `T` and release the memory. The
161- /// proper way to do so is to convert the raw pointer back into a
162- /// `Box` with the [`Box::from_raw`] function.
177+ /// caller should properly destroy `T` and release the memory, taking
178+ /// into account the [memory layout] used by `Box`. The easiest way to
179+ /// do this is to convert the raw pointer back into a `Box` with the
180+ /// [`Box::from_raw`] function, allowing the `Box` destructor to perform
181+ /// the cleanup.
163182 ///
164183 /// Note: this is an associated function, which means that you have
165184 /// to call it as `Box::into_raw(b)` instead of `b.into_raw()`. This
166185 /// is so that there is no conflict with a method on the inner type.
167186 ///
168- /// [`Box::from_raw`]: struct.Box.html#method.from_raw
169- ///
170187 /// # Examples
171- ///
188+ /// Converting the raw pointer back into a `Box` with [`Box::from_raw`]
189+ /// for automatic cleanup:
172190 /// ```
173- /// let x = Box::new(5 );
191+ /// let x = Box::new(String::from("Hello") );
174192 /// let ptr = Box::into_raw(x);
193+ /// let x = unsafe { Box::from_raw(ptr) };
194+ /// ```
195+ /// Manual cleanup by explicitly running the destructor and deallocating
196+ /// the memory:
175197 /// ```
198+ /// use std::alloc::{dealloc, Layout};
199+ /// use std::ptr;
200+ ///
201+ /// let x = Box::new(String::from("Hello"));
202+ /// let p = Box::into_raw(x);
203+ /// unsafe {
204+ /// ptr::drop_in_place(p);
205+ /// dealloc(p as *mut u8, Layout::new::<String>());
206+ /// }
207+ /// ```
208+ ///
209+ /// [memory layout]: index.html#memory-layout
210+ /// [`Box::from_raw`]: struct.Box.html#method.from_raw
176211 #[ stable( feature = "box_raw" , since = "1.4.0" ) ]
177212 #[ inline]
178213 pub fn into_raw ( b : Box < T > ) -> * mut T {
@@ -184,7 +219,7 @@ impl<T: ?Sized> Box<T> {
184219 /// After calling this function, the caller is responsible for the
185220 /// memory previously managed by the `Box`. In particular, the
186221 /// caller should properly destroy `T` and release the memory. The
187- /// proper way to do so is to convert the `NonNull<T>` pointer
222+ /// easiest way to do so is to convert the `NonNull<T>` pointer
188223 /// into a raw pointer and back into a `Box` with the [`Box::from_raw`]
189224 /// function.
190225 ///
@@ -203,6 +238,10 @@ impl<T: ?Sized> Box<T> {
203238 /// fn main() {
204239 /// let x = Box::new(5);
205240 /// let ptr = Box::into_raw_non_null(x);
241+ ///
242+ /// // Clean up the memory by converting the NonNull pointer back
243+ /// // into a Box and letting the Box be dropped.
244+ /// let x = unsafe { Box::from_raw(ptr.as_ptr()) };
206245 /// }
207246 /// ```
208247 #[ unstable( feature = "box_into_raw_non_null" , issue = "47336" ) ]
0 commit comments