std::vector:<T>:resize(n) vs reserve(n) with operator[]

std::vector<T>::resize(n) vs reserve(n) with operator[]

本文关键字:reserve operator with vs resize vector lt gt std      更新时间:2023-10-16

许多问题/答案告诉我std::vector<T>::resize(n)将增加容量和大小,而std::vector<T>::reserve(n)只增加容量。

一个例子是vector::resize()和vector::reserve()之间的选择。

问题中的注释表明,在使用reserve(n)之后,使用

vec[i less than n] = ..

是未定义的行为,许多给出的例子被认为会导致段错误。

编译并运行

#include <vector>
#include <iostream>
void f(const std::vector<double> &s) {
    std::cout << "s.size() = " << s.size() << std::endl;
    std::cout << "s.capacity() = " << s.capacity() << std::endl;
}
int main() {
    std::size_t n = 20121;
    
    std::vector<double> a;
    a.reserve(2*n);
    a[n] = 2.5;
    std::cout << "a["<<n<<"] = " << a[n] << std::endl;
    f(a);
    
    std::vector<double> b;
    b.resize(2*n);
    b[n] = 2.5;
    std::cout << "b["<<n<<"] = " << b[n] << std::endl;
    f(b);
}

输出是

a[20121] = 2.5

s.size() = 0

s.capacity() = 40242

b[20121] = 2.5

s.size() = 40242

s.capacity() = 40242

问题:

有什么变化使它可以吗?这只是我的编译器(g++ v5.2.0)给我未定义,但很好,行为吗?

作为第二个好奇点,为什么f(a)告诉我大小是0(猜测答案:没有push_back调用),即使a[n]返回一个有效值?

根据定义,"Undefined Behavior"意味着您在执行该行时看到的结果是未定义的,并且可以/将随着不同的运行而改变。

这只是我的编译器(g++ v5.2.0)给我未定义,但很好,行为呢?

好的行为可以是std::vector在编译版本中的实现方式和程序执行时的内存状态的混合。编译器在显示"良好行为"方面几乎没有任何作用。

一行回答:你注意到的确实是未定义行为。运行时可以自由地提供任何输出/行为,包括在击中UB时从显示器中射击猴子。

与未定义行为一样,编译器可能会产生您可能认为是"合理/不错"的行为,但是您看到"不错"的行为并不意味着您所做的是可以的!此行为可能随时改变,使用任何新版本的编译器,当您在任何其他机器或操作系统上编译和/或运行它时,或者当您在不同的月相中重新运行您的程序时。