Rust Book Quiz Ch 15.5, Interior Mutability

Hello!

I am currently working through the Rust Book (Brown University version). The quizzes really help a lot to keep me on my toes, but now I stumbled upon a question / solution I don't fully understand.

The final quiz of Chapter 15.5 asks which of the code snippets would violate memory safety.

I get why this would be the case in the correct answer (the vector could have been relocated due to the push, so the reference to its first element might be invalid).

But I don't understand why option 4 would be fine. My reasoning: with the first push, the vector might have been relocated, so the push with the second reference might be referencing an invalid location.

So I am clearly missing something here! :sweat_smile:

Could anybody give me a hint? I would really appreciate it!

Best regards!

Its more like the underlying buffer of the vector can reallocate due to the push, not the vector itself. The vector itself is basically a fat pointer consisting of length and capacity fields plus a pointer to some heap-allocated memory containing the vector's elements. If the capacity of the heap-allocation is too little to fit another element when it is pushed, a new heap allocation is created, causing the reallocation of the previous elements to the new location. So references inside the vector (i.e. to its elements) are problematic, if they were allowed to exist while one could still push new elements to the vector.

3 Likes

While it's true that the vector itself remains unmoved due to push(), so option 4 does not contain any dangling pointers, it is in fact UB. From Behavior considered undefined - The Rust Reference:

Rust code is incorrect if it exhibits any of the behaviors in the following list.

  • Breaking the pointer aliasing rules. … &mut T must point to memory that is not read or written by any pointer not derived from the reference and that no other reference points to while they are live.

v1 and v2 are both &mut Vec<i32>, and v2 points to memory which is mutated while v2 is live (through v1, which is not derived from v2), so this code contains UB.

Unfortunately, the Brown version of the book is teaching an incorrect “what the hardware does” model of undefined behavior; it seems to be written as if you replaced all & and &mut with raw pointers, and then asked whether the program executes UB. The stated justification for this is that it’s intended to teach why you need borrow checking, not how to write unsafe code. You can see argument at length about this matter in this open issue: "What if borrowck was off" quizes ignore the aliasing model UB · Issue #265 · cognitive-engineering-lab/rust-book · GitHub.

3 Likes

Ah, I was completely unaware of this! But now it makes sense to me. This is such a good explanation, I wish they had included it in the quiz solution! :slightly_smiling_face:

Thank you so much!

1 Like

This is good to know!

Many of the quiz questions that were worded like "This code does not compile, but now we pretend it compiles, so what would be the problem" were so confusing to me, and I spend a lot of time trying to understand the answers. :sweat_smile:

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.