未定义的行为 std::vector

undefined behavior std::vector

提问人:python_Skylake 提问时间:2/7/2023 更新时间:2/7/2023 访问量:32

问:

#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”打印为“预期”。

STL STD 标准向量

评论

0赞 Mooing Duck 2/7/2023
“我想知道程序如何能够处理项目分配”它没有处理它。
0赞 python_Skylake 2/7/2023
好的,你能解释一下会发生什么吗?
0赞 Community 2/7/2023
请澄清您的具体问题或提供其他详细信息,以准确说明您的需求。正如目前所写的那样,很难确切地说出你在问什么。

答:

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::allocatestd::allocatestd::allocate10

一种可能性是,内存中的地址当前未在进程中分配。操作系统会检测到这一点,通常它会使你的应用程序崩溃。 或者,它可能只是将该内存提供给您的应用,以便它继续运行。所以你永远不知道会发生什么。

另一种选择是,如果内存中的地址恰好已经在进程中分配,要么是巧合,要么是巧合,要么是其他东西,则写入成功写入内存中的该位置。希望这并不重要,就像网络代码一样,在这种情况下,下一次网络调用可以将内存中的内容(包括密码)发送到当时碰巧与之通信的任何服务器。或者,也许该内存目前没有用于任何事情,并且没有任何中断。或者,它可能连续工作 998 次,然后在第 999 次删除您的文件。不太可能,但有可能。std::allocate10

所以是的,大多数时候“未定义的行为无论如何都有效”。但不要这样做,你会后悔的。