【发布时间】:2020-08-23 10:29:55
【问题描述】:
我最近在网上了解到std::vector::reserve。网站说在std::vector 中保留内存不会改变向量的大小,而是增加std::vector 的容量。保留后,尝试访问随机元素应该会崩溃。
但是,当我运行这段代码时:
#include <iostream>
#include <vector>
using namespace std;
int main(){
vector <int> v;
v.reserve(1000000);
v[4] = 5;
cout << v[4] << endl; // this line and the above line should cause errors
return 0;
}
什么都没有发生。程序运行并将5 打印到屏幕上,我根本没有收到任何错误。
我不确定我是否在这里犯了错误,那么有人可以告诉我为什么上面的程序会运行吗?
【问题讨论】:
-
未定义的行为意味着任何事情都可能发生;它不保证会崩溃。
-
v[4] = 5;这会导致越界访问,之后的所有内容都是 UB。试试v.at(4) = 5;,你会得到你期望的错误。 -
它会如何崩溃?内存已分配,内存不知道整个大小与容量的关系
-
您会看到终端学大量与 STL 函数和较低级别的 c api 调用一起使用,这就是为什么仔细阅读这些语言中的文档非常重要的原因
-
@harold,标准库实现可以告诉编译器假设索引小于大小。在这种假设下,编译器会优化此代码及其周围的代码,从而导致崩溃。例如,
std::string str(input); if (something) { v.reserve(1000000); v[4] = 5; str += "foo"; } cout << str[10];。当编译器知道v[4]导致 UB 时,它可以意识到 if 语句永远不会发生,str将保留其初始值(可能小于 11 个元素)。然后可能会发生常规的越界索引,这是常见的崩溃原因。