C++ 数组大小以及如何管理大型数组
c++ array size and how to manage large array?
我尝试使用筛子方法查找从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)
相关文章:
- 如何初始化由unique_ptr管理的数组的元素?
- 坚持将双指针管理的内存复制到二维数组
- 我正在努力处理多维数组输入和输出,我管理输入,但是打印无法按计划工作
- C++ 使用数组初始化时的 STL 向量内存管理
- 使用unique_ptr来管理三维数组
- 将字节数组从c 不受管理的dll传递到c#unity
- Delphi中的动态数组和内存管理
- 当动态创建一个包含另一个动态创建的结构数组的结构数组时,内存管理
- C++内存管理:从函数中的向量创建一个新数组
- 二维数组分配中的内存管理
- 如何有效地管理数组中的堆对象(C++)
- C++ 数组大小以及如何管理大型数组
- 如何管理固定数组中的对象
- 将静态数组转换为 char* 并管理类型转换
- Python数组管理C++等效程序
- 如何在c++中管理数组边界
- 如何管理指向对象的指针数组
- 线程64后数组的内存管理错误
- 内存管理:使用new操作符进行数组和动态分配
- 在c++中有效地管理数组二进制堆句柄