我可以调整从中移出的向量的大小吗?

时间:2019-03-07 23:01:42

标签: c++ c++11 cryptography move move-semantics

我有一些代码,我想绝对确保从其中移出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); } 不会留下秘密数据(想想加密密钥管理)。在我的类的move构造函数中,我做类似的事情:

{{1}}

如您所见,我将秘密向量从秘密向量中移出后重新使用。我看着

Reusing a moved container?

但是我不确定是否可以做到这一点(我不明白什么是“先决条件”)。

我的问题是:我可以调整从std :: vector移动的大小,对其执行一些操作,然后再将其调整为零吗?

3 个答案:

答案 0 :(得分:4)

  

[defns.valid]有效但未指定状态   除了满足对象的不变量和对对象的操作外,未指定对象的值   对象的行为与其指定的类型相同

     

[示例:如果类型为std :: vector的对象x处于有效但未指定的状态,则x.empty()可以为   无条件调用,并且仅当x.empty()返回false时才能调用x.front()。 —结束示例]

std::vector::resize没有任何先决条件。不管向量处于什么有效状态,对其进行大小调整都不会有不确定的行为(忽略由所包含元素的构造函数引起的UB;但是,当参数为0时,不会调用那些状态)。

答案 1 :(得分:4)

  

我的问题是:我可以调整从std :: vector移动的大小,对其执行一些操作,然后再将其调整为零吗?

从对象移出的对象应处于未指定但有效的状态。

因此,您有权调整其大小(无需任何先决条件)。 safe_zero,然后清除它。

  

(我不明白什么是“先决条件”)。

在某些状态条件下,对象必须不调用UB。

例如,operator[](std::size_t i)要求i < size()

resize()clear()没有要求。

答案 2 :(得分:2)

是的。如链接问题中所述,对象处于有效状态但未指定状态。这意味着您无法假设有关std::vector的内容。调用size是安全的,但返回的值可能与移动之前的值不同。向量的状态是有效的,这意味着里面没有悬空的指针或任何东西,包括resize在内的所有成员函数都可以正常工作。此外,调用resize是要调用的少数有意义的函数之一,因为它“指定”了向量的状态。