Skip to content

Commit 9fae750

Browse files
committed
remark on structs and mem::uninitialized
1 parent 2ab1783 commit 9fae750

File tree

1 file changed

+23
-1
lines changed

1 file changed

+23
-1
lines changed

src/unchecked-uninit.md

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,12 +116,34 @@ However when working with uninitialized memory you need to be ever-vigilant for
116116
Rust trying to drop values you make like this before they're fully initialized.
117117
Every control path through that variable's scope must initialize the value
118118
before it ends, if it has a destructor.
119-
*[This includes code panicking](unwinding.html)*. `MaybeUninit` helps a bit
119+
*[This includes code panicking](unwinding.html)*. `MaybeUninit` helps a bit
120120
here, because it does not implicitly drop its content - but all this really
121121
means in case of a panic is that instead of a double-free of the not yet
122122
initialized parts, you end up with a memory leak of the already initialized
123123
parts.
124124

125+
Note that, to use the `ptr` methods, you need to first obtain a *raw pointer* to
126+
the data you want to initialize. It is illegal to construct a *reference* to
127+
uninitialized data, which implies that you have to be careful when obtaining
128+
said raw pointer:
129+
* For an array of `T`, you can use `base_ptr.add(idx)` where `base_ptr: *mut T`
130+
to compute the address of array index `idx`. This relies on
131+
how arrays are laid out in memory.
132+
* For a struct, however, in general we do not know how it is laid out, and we
133+
also cannot use `&mut base_ptr.field` as that would be creating a
134+
reference. Thus, it is currently not possible to create a raw pointer to a field
135+
of a partially initialized struct, and also not possible to initialize a single
136+
field of a partially initialized struct. (A
137+
[solution to this problem](https://github.com/rust-lang/rfcs/pull/2582) is being
138+
worked on.)
139+
140+
One last remark: when reading old Rust code, you might stumble upon the
141+
deprecated `mem::uninitialized` function. That function used to be the only way
142+
to deal with uninitialized memory on the stack, but it turned out to be
143+
impossible to properly integrate with the rest of the language. Always use
144+
`MaybeUninit` instead in new code, and port old code over when you get the
145+
opportunity.
146+
125147
And that's about it for working with uninitialized memory! Basically nothing
126148
anywhere expects to be handed uninitialized memory, so if you're going to pass
127149
it around at all, be sure to be *really* careful.

0 commit comments

Comments
 (0)