TL;博士:
如何调整(调整 length
和 capacity
的)C++ STL vector 没有任何初始化 ?垃圾值是可以接受的!
问题
我知道 STL Vector 有 resize()
方法,但此方法涉及初始化 ,这可能是不必要的。
此外,我发现了一个 set_len()
Rust 中的函数正是我想要的。 C++ STL有没有办法(甚至是hacky)来实现这一点?set_len()
可以找到 Rust 中的文档 here .
编辑 1
unsafe fn
,果然如此),但我说的是那些 the_new_length_i_am_setting <= vec.capacity()
是 保证 (我已经 reserved()
正确)。 malloc()
之间的区别和 calloc()
是我所说的一个完美的类比。 read()
的字节s 或 recv()
s 直接调用同一个 vector ,而不使用额外的数组/缓冲区。 (我在 Rust 的 Vec 中使用 reserve()
然后 set_len()
实现了这一点,但我未能在 C++ STL 的 set_len()
中找到 vector
的等效函数。vector
在仅接受数组的 Linux 系统 API 上。调用realloc()
在 malloc()
-ed 数组肯定会做同样的事情,但它很容易出错,尤其是在处理索引时。 最佳答案
前言(可能很长,但很重要)
您可能会说“垃圾值”是可以接受的,但事实并非如此。因为当人们说他们的 C++ 代码中有垃圾值时,他们实际上并没有,他们实际上有未定义的行为。而且你不应该掉以轻心未定义的行为。请允许我引用 another answer of mine :
void foo();
void bar();
void test(bool cond)
{
int a; // uninitialized
if (cond)
a = 24;
if (a == 24)
foo();
else
bar();
}
用
true
调用上述函数的结果是什么? false
怎么样? ?test(true)
将明确调用foo()
.test(false)
呢? ?如果你回答:“这取决于变量 a
中的垃圾值,如果是 24
,它将调用 foo
,否则它将调用 bar
”,那么你完全错了。如果您调用
test(false)
程序访问一个未初始化的变量并具有未定义的行为,它是一个非法路径,因此编译器可以自由假设 cond
绝不是false
(因为否则程序将是非法的)。令人惊讶的是,启用优化的 gcc 和 clang 实际上做到了这一点,generate this assembly对于功能:test(bool):
jmp foo()
这个故事的寓意是UB就是UB。不要依赖任何一种行为。访问未初始化的变量或内存不会导致垃圾值,它会导致 UB,结果可能非常糟糕,非常令人惊讶且难以调试。
回到你的问题:不,
std::vector
没有办法分配您可以访问的未初始化内存。 IE。这是 UB,你应该 100% 不这样做:std::vector<int> v = ...;
v.reserve(v.size() + 100);
v[v.size()] = 11; // Access beyond vector's size,
// Undefined Behavior even if you reserved memory for it
I am aware that setting a length that is larger than the vector's capacity is undefined behavior
不,这不对:
std::vector::resize
void resize( size_type count );
Resizes the container to contain count elements.
If the current size is less than count, additional default-inserted elements are appended
当然,这样做的缺点是元素将被默认插入。但正如我所说,在
std:::vector
中没有办法解决这个问题。即使没有
std::vector
,理论上也不可能做你想做的事。 . C++ 中的对象生命周期规则存在一个长期存在的问题(尽管事实上它在实践中被忽略了)。有论文p0593r2它试图解决这个问题。但即使在标准中采用了解决方案,您仍然需要实现自己的容器以允许并执行您想要的操作。
关于C++ STL Vector 相当于 Rust 中的 set_len(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61434924/