【问题标题】:Why does the call to std::vector::back() crash my program为什么对 std::vector::back() 的调用会使我的程序崩溃
【发布时间】:2012-02-13 23:54:17
【问题描述】:

我不确定这段代码有什么问题:

std::vector<int> myVector(0);

if (myVector.back() == 12)
    myVector.push_back(12);

似乎在空向量上调用 back() 会使程序崩溃。

我不明白它为什么会崩溃?在调用back()之前我们需要检查向量的长度吗?还是可能是一个错误?

文档说,如果向量是空的,它会返回一个未定义的值。

【问题讨论】:

  • 我怀疑这相当于有人给您 -1 以使用 MSDN 作为您的参考而不是 C++ 标准。实现者可以进一步定义他们的实现在标准说是UB的情况下做什么,所以如果MS想要保证back()在空向量上使用时会返回,他们有权这样做。如果您使用的是 MSVC++,那么您有权阅读他们的文档。但它可能改为 -1,因为没有意识到以任何方式使用“未定义值”会导致崩溃。
  • @SteveJessop 我认为 MSDN 是 C++ 标准的实现。但是,在有效元素上调用方法(据我所知,空的 is 向量是有效元素)会使我的程序崩溃,这感觉很奇怪。好吧,如果标准是这样说的,那就这样吧:)
  • MSVC++ 是(大约)C++ 标准的一个实现。如果标准没有说明行为,其他实现的行为会有所不同。标准没有定义在空向量上调用 back() 的原因是实现不需要特殊情况代码。因此,他们可以选择比必须检查向量是否为空时更快,并在不同情况下做不同的事情。当你做错事时,它们很容易崩溃(或更糟)。这可能感觉很奇怪,但这是语言设计的一部分。

标签: c++ visual-c++ stl stdvector std


【解决方案1】:

我们需要在调用 back() 之前检查向量的长度吗?

一句话:是的。这是你的错误,你的向量是空的,所以没有“后退”元素。

文档应该说(如果有的话)在空向量上调用 back() 会导致未定义的行为,而不是它返回未定义的值。

【讨论】:

  • 出于某种原因,MSDN 确实说“返回值未定义”(msdn.microsoft.com/en-us/library/0532x4xk%28v=vs.80%29.aspx)。但它也说,“使用 _SECURE_SCL 1 进行编译时,如果您尝试访问空向量中的元素,则会发生运行时错误”。我不知道(a)为什么 MS 将引用称为“值”,或者(b)他们如何将“未定义值”的概念与使用时导致运行时错误的引用概念相提并论.但这个运行时错误很可能与提问者所描述的“崩溃”相同。
  • 我仍然认为在有效元素上调用方法会使我的程序崩溃很奇怪。
  • @MBen:但是你的向量中没有元素; back() 的前提条件是您的向量中至少有一个元素。这就是定义接口的方式。在尝试调用back()之前,您需要确保您的输入符合前提条件。
  • @MBen:回读您的评论,当您说“在有效元素上”时,您的意思是“在有效对象上”吗?我想我可能误解了你写的内容。
  • @CharlesBailey 是的,对不起,我的意思是一个空向量是一个有效的元素,它不是垃圾或 null,这就是我感到惊讶的原因:-)
【解决方案2】:

c++11 标准告诉我们:

23.3.2.8 / 3

对一个大小为零的数组调用 front() 或 back() 的效果是不确定的。

由于行为未定义,任何事情都可能发生。你很幸运撞车了。

【讨论】:

  • 我不认为我很幸运,在有效值上调用方法会使我的程序崩溃,这感觉很奇怪。
  • @MBen 在 UB 上出现程序崩溃是件好事,因为它很容易发现错误。当它有时有效有时无效时,很难找到错误。
  • 我同意。我只需要确保向量有元素:-)
猜你喜欢
  • 2011-06-10
  • 2012-08-04
  • 1970-01-01
  • 1970-01-01
  • 2017-03-26
  • 2012-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多