c ++数组大小以及如何管理大数组?

时间:2016-03-17 03:57:29

标签: c++ arrays memory-management

我尝试使用筛选方法查找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.I得到结果4203,因此从1到40000有4203个素数

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

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

为什么当数组大小为100000时,程序为carsh。当数组大小为40000时,该程序有效吗?我的代码有什么问题吗?

4 个答案:

答案 0 :(得分:4)

您有整数溢出问题。

您指定j = i*i。当i等于99999时,i*i9999800001,这很可能高于您平台上的INT_MAX。在32位平台上,INT_MAX2147483647,低于9999800001

这里有两行用于比较:

2147483647
9999800001

由于整数溢出,您的程序有不确定的行为。

答案 1 :(得分:2)

问题在于这一行:

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

i*i超出界限,j溢出并变为负数,使得这一行:

a[j] = '0';

段错误

答案 2 :(得分:1)

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

<input id="file1" type="file" value="" style="background-color: red;opacity:0;filter:alpha(opacity=0);cursor: pointer; padding-top:3px;width:25px;" name="file">

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

答案 3 :(得分:1)

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

回答一个潜在的后续问题:我怎么能首先避免/发现这个问题?好吧,一些编译器可以为未定义的行为提供运行时检测。

以下是我使用UBSan(what is 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)