I have some code in which I want to make absolutely sure that a moved-from std::vector
will not leave secret data around (think about crypto key management). In my class' move constructor, I do something like:
X(X&& rhs): secret_vector{std::move(rhs.secret_vector)}{
rhs.secret_vector.resize(N);
safe_zero(rhs.secret_vector); // zero out all elements
rhs.secret_vector.resize(0);
}
As you can see, I re-use the secret vector after moving from it. I looked at
Reusing a moved container?
but it was not absolutely clear that I can do this (I did not understand what "pre-conditions" really are).
My question is: can I resize a moved-from std::vector, perform some operation on it, then resize it back to zero?
My question is: can I resize a moved-from std::vector, perform some operation on it, then resize it back to zero?
A moved from object should be in unspecified but valid state.
So you have the right to resize it (no precondition required for that). safe_zero it, and clear it.
(I did not understand what "pre-conditions" really are).
There are state conditions that object should have to not invoke UB.
For example, operator[](std::size_t i)
requires that i < size()
.
resize()
, clear()
doesn't have requirements.
[defns.valid] valid but unspecified state value of an object that is not specified except that the object’s invariants are met and operations on the object behave as specified for its type
[Example: If an object x of type std::vector is in a valid but unspecified state, x.empty() can be called unconditionally, and x.front() can be called only if x.empty() returns false. — end example]
std::vector::resize
does not have any preconditions. No matter what valid state a vector is in, resizing it would not have undefined behaviour (disregarding UB caused by constructors of contained elements; but those are not called when the argument is 0).
Yes. The object is in valid but in unspecified state as stated in the linked question. That means that you cannot assume anything about the content of std::vector
. Calling size
is safe but it might not return the same value as before the move. The state of the vector is valid, meaning there are no dangling pointers inside or anything and all member functions including resize
will work just fine. Moreover calling resize is one of the few meaningful functions to call because it "respecifies" the vector's state.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With