@@ -127,24 +127,38 @@ impl<T: ?Sized> Box<T> {
127
127
///
128
128
/// After calling this function, the raw pointer is owned by the
129
129
/// 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.
130
+ /// the destructor of `T` and free the allocated memory. For this
131
+ /// to be safe, the memory must have been allocated in the precise
132
+ /// way that `Box` expects, namely, using the global allocator
133
+ /// with the correct [`Layout`] for holding a value of type `T`. In
134
+ /// particular, this will be satisfied for a pointer obtained
135
+ /// from a previously existing `Box` using [`Box::into_raw`].
136
+ ///
137
+ /// # Safety
134
138
///
135
139
/// This function is unsafe because improper use may lead to
136
140
/// memory problems. For example, a double-free may occur if the
137
141
/// function is called twice on the same raw pointer.
138
142
///
139
- /// [`Box::into_raw`]: struct.Box.html#method.into_raw
140
- ///
141
143
/// # Examples
142
- ///
144
+ /// Recreate a `Box` which was previously converted to a raw pointer using [`Box::into_raw`]:
143
145
/// ```
144
146
/// let x = Box::new(5);
145
147
/// let ptr = Box::into_raw(x);
146
148
/// let x = unsafe { Box::from_raw(ptr) };
147
149
/// ```
150
+ /// Manually create a `Box` from scratch by using the global allocator:
151
+ /// ```
152
+ /// use std::alloc::{Layout, alloc};
153
+ ///
154
+ /// let ptr = unsafe{ alloc(Layout::new::<i32>()) } as *mut i32;
155
+ /// unsafe{ *ptr = 5; }
156
+ /// let x = unsafe{ Box::from_raw(ptr) };
157
+ /// ```
158
+ ///
159
+ /// [`Layout`]: ../alloc/struct.Layout.html
160
+ /// [`Box::into_raw`]: struct.Box.html#method.into_raw
161
+ ///
148
162
#[ stable( feature = "box_raw" , since = "1.4.0" ) ]
149
163
#[ inline]
150
164
pub unsafe fn from_raw ( raw : * mut T ) -> Self {
@@ -158,21 +172,34 @@ impl<T: ?Sized> Box<T> {
158
172
/// After calling this function, the caller is responsible for the
159
173
/// memory previously managed by the `Box`. In particular, the
160
174
/// 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.
175
+ /// easiest way to do so is to convert the raw pointer back into a `Box`
176
+ /// with the [`Box::from_raw`] function.
163
177
///
164
178
/// Note: this is an associated function, which means that you have
165
179
/// to call it as `Box::into_raw(b)` instead of `b.into_raw()`. This
166
180
/// is so that there is no conflict with a method on the inner type.
167
181
///
168
- /// [`Box::from_raw`]: struct.Box.html#method.from_raw
169
- ///
170
182
/// # Examples
171
- ///
183
+ /// Converting the raw pointer back into a `Box` with [`Box::from_raw`]
184
+ /// for automatic cleanup:
172
185
/// ```
173
- /// let x = Box::new(5 );
186
+ /// let x = Box::new(String::from("Hello") );
174
187
/// let ptr = Box::into_raw(x);
188
+ /// let x = unsafe{ Box::from_raw(ptr) };
189
+ /// ```
190
+ /// Manual cleanup by running the destructor and deallocating the memory:
175
191
/// ```
192
+ /// use std::alloc::{Layout, dealloc};
193
+ /// use std::ptr;
194
+ ///
195
+ /// let x = Box::new(String::from("Hello"));
196
+ /// let p = Box::into_raw(x);
197
+ /// unsafe{ ptr::drop_in_place(p); }
198
+ /// unsafe{ dealloc(p as *mut u8, Layout::new::<String>()); }
199
+ /// ```
200
+ ///
201
+ /// [`Box::from_raw`]: struct.Box.html#method.from_raw
202
+ ///
176
203
#[ stable( feature = "box_raw" , since = "1.4.0" ) ]
177
204
#[ inline]
178
205
pub fn into_raw ( b : Box < T > ) -> * mut T {
@@ -184,7 +211,7 @@ impl<T: ?Sized> Box<T> {
184
211
/// After calling this function, the caller is responsible for the
185
212
/// memory previously managed by the `Box`. In particular, the
186
213
/// caller should properly destroy `T` and release the memory. The
187
- /// proper way to do so is to convert the `NonNull<T>` pointer
214
+ /// easiest way to do so is to convert the `NonNull<T>` pointer
188
215
/// into a raw pointer and back into a `Box` with the [`Box::from_raw`]
189
216
/// function.
190
217
///
@@ -203,6 +230,10 @@ impl<T: ?Sized> Box<T> {
203
230
/// fn main() {
204
231
/// let x = Box::new(5);
205
232
/// let ptr = Box::into_raw_non_null(x);
233
+ ///
234
+ /// // Clean up the memory by converting the NonNull pointer back
235
+ /// // into a Box and letting the Box be dropped.
236
+ /// let x = unsafe{ Box::from_raw(ptr.as_ptr()) };
206
237
/// }
207
238
/// ```
208
239
#[ unstable( feature = "box_into_raw_non_null" , issue = "47336" ) ]
0 commit comments