【问题标题】:Please, can some one tell me what's wrong with this code?拜托,有人能告诉我这段代码有什么问题吗?
【发布时间】:2021-05-22 02:00:23
【问题描述】:

请问有人能告诉我这段代码有什么问题吗?

#include <iostream>
using namespace std;
int main() {
    int a[3], i;
    for(i = 0; i <= 3; i++ )
        {
            a[i] = 0;
            cout << "i = " << i << endl;
        }
    return 0;
}

【问题讨论】:

  • 数组的索引是从 0 到 2,所以你超出了范围。将循环更改为for(i = 0; i &lt; 3; i++ )。
  • 数组索引从零开始,具有三个元素的数组的最大索引是两个,即a 有元素a[0]、a[1] 和a[2],但没有a[3]。因此,您的循环太过分了一个元素,并修改了不存在的a[3]。将循环中的结束条件从 i &lt;= 3 更改为 i &lt; 3 以解决该问题。
  • 是什么让你觉得有些不对劲?请准确描述您遇到的问题。
  • 我可能会争辩说这段代码没有任何问题,只要代码的意图是调用未定义的行为。 :) 好的,冷静下来。我的观点是,如果没有描述什么是正确的(即预期结果),就没有理由假设实际结果是错误的。这让我们回到了 cigien 的评论以及需要更多文字以使这个问题对其他人有用。

标签: c++ for-loop infinite-loop local-variables off-by-one


【解决方案1】:

此代码的数组长度仅为3,但for循环执行4次,因为循环从0到3执行。i的值将如下所示:

i = 0
i = 1
i = 2
i = 3

由于数组a[3]的长度为3,但是你尝试将4元素放入其中当然会报错:

*** stack smashing detected ***: terminated
Aborted (core dumped)

修复

尝试改变数组长度或循环条件。

【讨论】:

  • 将四个元素放入一个数组不一定“显示错误”。行为未定义。代码中有很多与从数组末尾脱落和修改其他内容相关的错误,但不一定会报告错误。其他症状 - 许多 C++ 开发人员都经历过艰难的方式 - 这样的循环似乎可以正常工作,但是其他一些不相关代码中的一些其他变量 - 恰好在数组末尾之后立即占用内存 - 神秘变化。确实会发生此类错误,并且很难追踪。
  • “它会显示一个错误”——如果这是真的。该行为是未定义的,并且不需要实现来产生运行时错误。更有可能的是,它要么起作用(当你测试它时),要么你会得到一些奇怪的行为(当你把它运送给客户时)。
  • @Bungo - 有趣的(咳咳!)案例是当它在您的测试中起作用并且对客户表现出奇怪的行为时。
  • @Peter - 是的,这就是我的意思。解决这些错误非常有趣......顺便说一句,值得注意的是,由于不正确的索引导致的未定义行为并不是普通的旧 C 样式数组所独有的,但在使用 operator[] 时同样适用于 std::vector 和 std::array(而不是.at())。我认识一些相对资深的开发人员,他们没有意识到这一点。
  • @Bungo - 这是我在可能的情况下更喜欢迭代器而不是数组索引的原因之一。不会消除运行太远的可能性(例如,取消引用结束迭代器),但使用索引更容易产生此类错误。更好的是完全避免使用原始数组或指针,并且(C++11 及更高版本)使用基于范围的 for 循环(然后故意运行超过容器,更不用说意外了)。
猜你喜欢
  • 2020-02-21
  • 2020-10-30
  • 2010-11-08
  • 1970-01-01
  • 2021-10-14
  • 2013-05-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多