提问人:python_Skylake 提问时间:2/7/2023 更新时间:2/7/2023 访问量:32
未定义的行为 std::vector
undefined behavior std::vector
问:
#include <iostream>
#include <string>
#include <vector>
int main()
{
std::string name;
std::vector<double> v(5, 1);
std::cout<<v.capacity()<<std::endl;
v[1000000]= 10.;
std::cout<<v[1000000]<<std::endl;
std::cout<<v.capacity()<<std::endl;
return 0;
}
此代码是未定义的行为吗?似乎没有即时进行分配,所以我想知道该程序如何能够处理项目分配。我正在使用 OSX Monterrey,这将“10”打印为“预期”。
答:
0赞
Mooing Duck
2/7/2023
#1
std::vector<double> v(5, 1);
std::cout<<v.capacity()<<std::endl;
v[1000000]= 10.;
从你的问题中,我很确定你知道这是未定义的行为。你的问题实际上是“为什么这个不崩溃?
未定义的行为意味着任何事情都可能发生。通常发生的事情是应用程序似乎可以工作。向量将要求 ~20 字节的内存,并要求操作系统提供一大块内存,然后向量提供 20 字节的内存,然后它将保存大块的其余部分,以备下次要求更多内存。然后,您的代码分配给(虚拟)内存中的位置,该位置比分配给向量的内存高出 ~4MB。std::allocate
std::allocate
std::allocate
10
一种可能性是,内存中的地址当前未在进程中分配。操作系统会检测到这一点,通常它会使你的应用程序崩溃。 或者,它可能只是将该内存提供给您的应用,以便它继续运行。所以你永远不知道会发生什么。
另一种选择是,如果内存中的地址恰好已经在进程中分配,要么是巧合,要么是巧合,要么是其他东西,则写入成功写入内存中的该位置。希望这并不重要,就像网络代码一样,在这种情况下,下一次网络调用可以将内存中的内容(包括密码)发送到当时碰巧与之通信的任何服务器。或者,也许该内存目前没有用于任何事情,并且没有任何中断。或者,它可能连续工作 998 次,然后在第 999 次删除您的文件。不太可能,但有可能。std::allocate
10
所以是的,大多数时候“未定义的行为无论如何都有效”。但不要这样做,你会后悔的。
评论