大矢量"分段故障"错误

时间:2015-06-02 23:56:27

标签: c++ vector segmentation-fault

我从其他人那里收集了大量非常有用的信息。关于SO的问题和答案,并且已经适当地搜索了这个问题的答案。不幸的是我没有找到解决这个问题的方法。

以下函数生成素数列表:

void genPrimes (std::vector<int>* primesPtr, int upperBound = 10)
{
  std::ofstream log;
  log.open("log.txt");

  std::vector<int>& primesRef = *primesPtr;

  // Populate primes with non-neg reals
  for (int i = 2; i <= upperBound; i++)
    primesRef.push_back(i);
  log << "Generated reals successfully." << std::endl;
  log << primesRef.size() << std::endl;

  // Eratosthenes sieve to remove non-primes
  for (int i = 0; i < primesRef.size(); i++) {
    if (primesRef[i] == 0) continue;
    int jumpStart = primesRef[i];
    for (int jump = jumpStart; jump < primesRef.size(); jump += jumpStart) {
      if (primesRef[i+jump] == 0) continue;
      primesRef[i+jump] = 0;
    }
  }
  log << "Executed Eratosthenes Sieve successfully.\n";

  for (int i = 0; i < primesRef.size(); i++) {
    if (primesRef[i] == 0) {
      primesRef.erase(primesRef.begin() + i);
      i--;
    }
  }
  log << "Cleaned list.\n";
  log.close();
}

被称为:

  const int SIZE = 500;
  std::vector<int>* primes = new std::vector<int>[SIZE];
  genPrimes(primes, SIZE);

此代码效果很好。但是,当我将SIZE的值更改为更大的数字(例如,500000)时,编译器会返回&#34;分段错误。&#34;我不太熟悉矢量来理解这个问题。非常感谢任何帮助。

4 个答案:

答案 0 :(得分:2)

您正在访问primesRef[i + jump],其中i可能是primesRef.size() - 1jump可能是primesRef.size() - 1,从而导致超出界限。

正在发生500限制,这恰好是您目前没有任何不良的副作用。

另请注意,在此使用vector是一个不错的选择,因为每次擦除都必须移动内存中的所有以下条目。

答案 1 :(得分:1)

你确定要做吗

 new std::vector<int> [500];

而不是

new std::vector<int> (500);

在后一种情况下,您指定了矢量的大小,其位置可通过名为“primes”的变量使用。

在前者中,您要求500个向量的空间,每个向量的大小都是ST​​L库所需的默认值。

这就像(在我的系统上:24 * 500字节)。在后一种情况下,您需要500长度向量(只有一个向量)。

编辑:看一下用法 - 他只需要一个向量。

的std ::矢量&安培; primesRef = * primesPtr;

答案 2 :(得分:0)

问题在于:

  // Populate primes with non-neg reals
  for (int i = 2; i <= upperBound; i++)
    primesRef.push_back(i);

你的向量中只有N-2个元素被推回,但是后来尝试访问N-1的元素(i + jump)。它没有在500上失败的事实只是愚蠢的运气,被覆盖的内存不是灾难性的。

答案 3 :(得分:0)

  

此代码效果很好。但是,当我将SIZE的值更改为更大的数字(例如,500000)时,...

这可能会给你的筹码带来不利影响。您需要为您认为需要的所有std::vector<int>个实例分配动态内存。

要实现这一点,只需使用这样的嵌套std::vetcor

 std::vector<std::vector<int>> primes(SIZE);

代替。

但为了直截了当,我严重怀疑你需要多少SIZE个矢量实例来存储找到的所有素数,但只有一个初始化如下:

 std::vector<int> primes(SIZE);