【问题标题】:Segmentation fault with vectors, but not sure what I did wrong向量的分段错误,但不确定我做错了什么
【发布时间】:2021-01-24 20:36:59
【问题描述】:

所以当我运行这段代码时:

#include <iostream>
using namespace std;
#include <vector>
#include <string>
int main()
{
   int current_number = 0;
   vector<int>primes;
   for(int i = 0; i < 100; i++)
   {
      current_number++;
      for(int h= 0; h < primes.size(); h++)
      {
         if(current_number % primes[h] == 0)
         {
            continue;
         }
         else
         {
            primes.push_back(current_number);
         }
      }
   }
   for(int x =0; x < 100; x++)
   {
      cout << primes[x];
   }
}

我遇到了分段错误。我很确定它与vectorprimes有关。但是,我不确定到底是什么。代码的目的是找出 1 到 100 之间的每个素数。

【问题讨论】:

  • 您是否注意到内部 for 循环体从未执行,因为 primes 在开始时为空且从未更改?例如。 h &lt; primes.size() 在没有进入循环体的情况下在初始和抛弃时是错误的。这段代码最终所做的就是将计数器递增 100 次,然后执行一个硬 100 次迭代循环,该循环取消引用 primes 中不存在的单元格。 使用调试器。单步执行此代码会快速向您展示这一点。
  • 当我这样做时:vectorprimes = {2};,因此 primes 在开始时不为空,代码什么也不做。这就是我最初所做的,但我明白你的意思。
  • 一旦你这样做了,它仍然会被破坏,因为模数非零的每次迭代都会增加primes(从而拉长内部循环)。在 after 内部循环完成之前,您不想这样做,并且知道它在没有零模测试命中的情况下运行完成;不是每次失败的命中。仅供参考,代码中的最后一个循环应该是for (auto x : primes) { std::cout &lt;&lt; x &lt;&lt; ' '; }
  • 啊,我明白了,谢谢。
  • for(int x =0; x &lt; 100; x++) 不够谨慎。我更喜欢for(unsigned x = 0; x &lt; primes.size(); x++),然后我确定我不会在循环内超出primes。当然for (auto value: primes)在这里会更好。

标签: c++ vector


【解决方案1】:

在发布的代码中存在的问题。

  • 永远不会输入内部循环体,因为 primes 最初是空的,唯一改变它的代码是在该循环中。
  • 即使在使用{2} 修复初始素数内容并使用3 启动计数器循环后,内部循环中的逻辑仍然是错误的。它附加在非零模上。 根本不应该在内循环中这样做。相反,循环应该在任何零模上中断,然后外部循环仅在知道内部循环没有提前中断时才附加到 primes
  • 最终的报告循环假定前 100 个数字中有 100 个素数,显然情况并非如此。它应该基于容器大小进行迭代,使用迭代器,或者更好的是,只使用 ranged-for。
  • 次要:current_number 毫无意义;只需使用外部循环中的i 并从3 开始。
#include <iostream>
#include <vector>

int main()
{
    std::vector<int> primes = {2};
    for (int i = 3; i <= 100; i++)
    {
        bool isprime = true;
        for (auto x : primes)
        {
            if (i % x == 0)
            {
                isprime = false;
                break;
            }
        }

        if (isprime)
            primes.emplace_back(i);
    }

    for (auto x : primes)
        std::cout << x << ' ';
    std::cout << '\n';
}

输出

2 3 5 7 11 13 17 19 23 29 31 37 41 43 47 53 59 61 67 71 73 79 83 89 97

注意

有更好的方法来做到这一点。我建议您研究如何构建Sieve of Eratosthenes 或类似的筛子。事实上,上面的代码已经完成了一半。不需要太多。

【讨论】:

  • 这帮助我更彻底地看到了问题,谢谢!
猜你喜欢
  • 2014-03-23
  • 2022-01-06
  • 1970-01-01
  • 1970-01-01
  • 2010-11-08
  • 2014-06-21
  • 2017-09-29
  • 1970-01-01
  • 2021-03-05
相关资源
最近更新 更多