std::vector reserve() 的未定义行为
Undefined behavior for std::vector reserve()
考虑以下代码:
vector<uint8_t> v(1);
v.reserve(2);
uint8_t *data = &v.front();
data[1] = 0;
是否存在未定义的行为(C++98、C++03、C++11)?
如果是,获得 RAII 缓冲区的最佳方法是什么(不使用 C++11)?
每当 v.empty()
为真时调用 v.front()
是未定义的行为。调用 v[n]
是未定义的行为,除非 n < v.size()
。此外,保留内存中没有 objects,因此您不能将内存视为对象。一个向量只保证
that [data(), data() + size())
is a valid range
并且不保证有更大的有效范围。 (请注意 data() == &front()
,因此这适用于您的代码。)
我查了C++98标准。
这里是 reserve() 的注释:
“保证在调用 reserve() 之后发生的插入期间不会发生重新分配,直到插入会使向量的大小大于在最近调用 reserve()。”
并且来自 "vector modifiers" 的注释:
"如果没有发生重新分配,插入点之前的所有迭代器和引用仍然有效。"
因此,存在问题的恕我直言代码即使对于 C++98 也是完全有效的。
考虑以下代码:
vector<uint8_t> v(1);
v.reserve(2);
uint8_t *data = &v.front();
data[1] = 0;
是否存在未定义的行为(C++98、C++03、C++11)?
如果是,获得 RAII 缓冲区的最佳方法是什么(不使用 C++11)?
每当 v.empty()
为真时调用 v.front()
是未定义的行为。调用 v[n]
是未定义的行为,除非 n < v.size()
。此外,保留内存中没有 objects,因此您不能将内存视为对象。一个向量只保证
that
[data(), data() + size())
is a valid range
并且不保证有更大的有效范围。 (请注意 data() == &front()
,因此这适用于您的代码。)
我查了C++98标准。
这里是 reserve() 的注释:
“保证在调用 reserve() 之后发生的插入期间不会发生重新分配,直到插入会使向量的大小大于在最近调用 reserve()。”
并且来自 "vector modifiers" 的注释:
"如果没有发生重新分配,插入点之前的所有迭代器和引用仍然有效。"
因此,存在问题的恕我直言代码即使对于 C++98 也是完全有效的。