C++ 数组大小以及如何管理大型数组

c++ array size and how to manage large array?

本文关键字:数组 管理 大型 何管理 C++      更新时间:2023-10-16

我尝试使用筛子方法查找从1到100000的素数数量。这是我的代码:

#include <iostream>
#include <cstring>
using namespace std;
int main()
{
    char *a = new char[100000];
    memset(a, '1', 100000*sizeof(char));
    for(int i=2; i<100000; i++)
    {
         if(a[i] == '1')
         {
              for(int j=i*i; j<100000; j += i)
              {
                   a[j] = '0';
              }
         }
    }
    int count = 0;
    for(int i=2; i<100000; i++)
    {
         if(a[i] == '1')
              count++;
    }
    cout << count << endl;
    delete [] a;
    return 0;
}

这段代码编译没有错误,但是当我运行它时,程序崩溃了。

我将数组大小从 100000 更改为 40000.我得到的结果是 4203,所以从 4203 到 40000 有 4203 个质数

我知道我的 32 位操作系统中数组的最大字节是 0x7fffffff 字节。

100000 个字符

或 40000 个字符远小于 0x7fffffff 字节。

为什么当数组大小为

100000时,程序carsh.当数组大小为40000时,程序工作?我的代码有问题吗?

您有一个整数溢出问题。

您分配j = i*i .当i等于 99999 时,i*i 9999800001 ,这很可能高于您平台上的INT_MAX。在 32 位平台上,INT_MAX 2147483647 ,低于 9999800001

在这里,它们分为两行进行比较:

2147483647
9999800001

由于整数溢出,程序具有未定义的行为。

问题是这一行:

for(int j=i*i; j<100000; j += i)

i*i 超出界,j 溢出并变为负数,使这条线:

a[j] = '0';

段错误

为什么需要使用数组?您可以考虑使用更简单的算法,例如:

#include  <iostream>
using  namespace  std;
    int  main()
    {
      int  N;
      int count = 0;
      cin >> N;
      for (int i = 2; N > 0; ++i)
      {
        bool  isPrime = true;
        for (int j = 2; j < i; ++j)
        {
          if (i  % j == 0)
          {
            isPrime = false;
            break;
          }
        }
        if (isPrime)
        {
          if (i > N)
            break;
          count++;
          cout << i << "n";
        }
      }
      cout << "The number of primes from 0 to " << N << " is " << count << endl;
      char stop;
      cin >> stop;
      return  0;
    }

此算法输出 9592 作为从 0 到 100000 的素数数。

关于溢出的所有其他答案都是正确的。

回答一个潜在的后续问题:我如何首先避免/检测到这种情况? 好吧,一些编译器可以为未定义的行为提供运行时检测。

以下是我使用 UBSan 运行您的代码时得到的(什么是 UBSan?

$ clang++ -fsanitize=undefined  overflow.cpp 
$ ./a.out 
overflow.cpp:14:26: runtime error: signed integer overflow: 46349 * 46349 cannot be represented in type 'int'
Segmentation fault (core dumped)

作为参考,第 #14 行是这样的:

          for(int j=i*i; j<100000; j += i)