File tree 2 files changed +14
-2
lines changed
2 files changed +14
-2
lines changed Original file line number Diff line number Diff line change 62
62
//! T` obtained from [`Box::<T>::into_raw`] may be deallocated using the
63
63
//! [`Global`] allocator with [`Layout::for_value(&*value)`].
64
64
//!
65
+ //! For zero-sized values, the `Box` pointer still has to be [valid] for reads and writes and
66
+ //! sufficiently aligned. In particular, casting any aligned non-zero integer to a raw pointer
67
+ //! produces a valid pointer, but a pointer pointing into previously allocated memory that since got
68
+ //! freed is not valid.
69
+ //!
65
70
//! So long as `T: Sized`, a `Box<T>` is guaranteed to be represented
66
71
//! as a single pointer and is also ABI-compatible with C pointers
67
72
//! (i.e. the C type `T*`). This means that if you have extern "C"
125
130
//! [`Global`]: crate::alloc::Global
126
131
//! [`Layout`]: crate::alloc::Layout
127
132
//! [`Layout::for_value(&*value)`]: crate::alloc::Layout::for_value
133
+ //! [valid]: ptr#safety
128
134
129
135
#![ stable( feature = "rust1" , since = "1.0.0" ) ]
130
136
@@ -385,7 +391,10 @@ impl<T: ?Sized> Box<T> {
385
391
/// memory problems. For example, a double-free may occur if the
386
392
/// function is called twice on the same raw pointer.
387
393
///
394
+ /// The safety conditions are described in the [memory layout] section.
395
+ ///
388
396
/// # Examples
397
+ ///
389
398
/// Recreate a `Box` which was previously converted to a raw pointer
390
399
/// using [`Box::into_raw`]:
391
400
/// ```
Original file line number Diff line number Diff line change 16
16
//! provided at this point are very minimal:
17
17
//!
18
18
//! * A [null] pointer is *never* valid, not even for accesses of [size zero][zst].
19
- //! * All pointers (except for the null pointer) are valid for all operations of
20
- //! [size zero][zst].
21
19
//! * For a pointer to be valid, it is necessary, but not always sufficient, that the pointer
22
20
//! be *dereferenceable*: the memory range of the given size starting at the pointer must all be
23
21
//! within the bounds of a single allocated object. Note that in Rust,
24
22
//! every (stack-allocated) variable is considered a separate allocated object.
23
+ //! * Even for operations of [size zero][zst], the pointer must not be "dangling" in the sense of
24
+ //! pointing to deallocated memory. However, casting any non-zero integer to a pointer is valid
25
+ //! for zero-sized accesses. This corresponds to writing your own allocator; allocating zero-sized
26
+ //! objects is not very hard. In contrast, when you use the standard allocator, after memory got
27
+ //! deallocated, even zero-sized accesses to that memory are invalid.
25
28
//! * All accesses performed by functions in this module are *non-atomic* in the sense
26
29
//! of [atomic operations] used to synchronize between threads. This means it is
27
30
//! undefined behavior to perform two concurrent accesses to the same location from different
You can’t perform that action at this time.
0 commit comments