繁体   English   中英

大向量“分段故障”错误

[英]Large vector “Segmentation fault” error

我从其他人关于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)时,编译器将返回“分段错误”。 我对向量不足以了解问题。 任何帮助深表感谢。

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

限制为500,这是因为您碰巧目前没有由于出入限制而造成的任何不良影响。

还要注意,在这里使用vector是一个不好的选择,因为每次擦除都必须将以下所有条目移动到内存中。

确定要做吗

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

并不是

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

在后一种情况下,您要指定向量的大小,可以通过名为“ primes”的变量来获得向量的位置。

在前一种情况下,您需要500个向量的空间,每个向量的大小均应为STL库所需的默认值。

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

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

std :: vector&primesRef = * primesPtr;

问题出在这里:

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

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

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

这可能会打击您的堆栈,并为其分配大量资源。 您需要为您认为需要的所有std::vector<int>实例动态分配内存。

为此,只需使用嵌套的std::vetcor这样。

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

代替。

但是要继续讲下去,我严重怀疑您是否需要大量SIZE向量实例来存储找到的所有质数,但是只有一个这样初始化:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM