如何分配一个当前在分配过程中抛出 std::bad_alloc 错误的大量布尔数组
How can I allocate a massive boolean array that currently throws std::bad_alloc errors during allocation?
我已经看到了几个与此相关的问题,但我想验证我是否遇到了类似的问题。我的代码分配了一个包含大量元素的布尔数组。这是我的代码,在x86_64 Linux 机器上编译:
#include <iostream>
#include <math.h>
using std::cout;
using std::endl;
using std::nothrow;
long problem3()
{
long upper_bound = 600851475143;
long max_prime_factor = 1;
long max_possible_prime = (long) sqrt(upper_bound) + 1;
bool * primes;
primes = new (nothrow) bool[upper_bound];
primes[0] = false; //segmentation fault occurs here
primes[1] = false;
for (long i = 2; i < upper_bound; i++)
primes[i] = true;
for (long number = 2; number < max_possible_prime; number++)
{
if (primes[number] == true)
{
if (upper_bound % number == 0)
{
max_prime_factor = number;
}
for (long j = number + number; j < upper_bound; j += number)
primes[j] = false;
}
else { continue; }
}
return max_prime_factor;
}
int main ( int argc, char *argv[] )
{
cout<<"Problem 3: "<<problem3()<<endl;
}
构建此代码并按原样运行它会在以下行上给出分段错误:
primes[0] = false
如果我删除nothrow
指令以更改此行:
primes = new (nothrow) bool[upper_bound];
对此:
primes = new bool[upper_bound];
我收到一条错误消息,指出:
terminate called after throwing an instance of 'std::bad_alloc'
我认为这意味着分配失败,可能是因为大小(基于类似的问题和其他参考链接。
CodeBlock 中的调试器显示,即使在应该分配primes
之后,仍设置为0x0
。瓦尔格林德证实了这一点:
==15436== Command: ./main
==15436==
==15436== Invalid write of size 1
==15436== at 0x400A81: problem3() (main.cpp:54)
==15436== by 0x400B59: main (main.cpp:77)
==15436== Address 0x0 is not stack'd, malloc'd or (recently) free'd
==15436==
==15436==
==15436== Process terminating with default action of signal 11 (SIGSEGV)
==15436== Access not within mapped region at address 0x0
==15436== at 0x400A81: problem3() (main.cpp:54)
==15436== by 0x400B59: main (main.cpp:77)
==15436== If you believe this happened as a result of a stack
==15436== overflow in your program's main thread (unlikely but
==15436== possible), you can try to increase the size of the
==15436== main thread stack using the --main-stacksize= flag.
==15436== The main thread stack size used in this run was 8388608.
==15436==
==15436== HEAP SUMMARY:
==15436== in use at exit: 0 bytes in 0 blocks
==15436== total heap usage: 1 allocs, 0 frees, 0 bytes allocated
==15436==
==15436== All heap blocks were freed -- no leaks are possible
==15436==
==15436== For counts of detected and suppressed errors, rerun with: -v
==15436== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 3 from 3)
Segmentation fault
问:我知道std::vector
,所以我应该使用它来分配这个数组吗?我也愿意尝试不同的算法,但我想知道我是否缺少C++细微差别,允许我分配这样的数组(即使它绝对很大,我理解这一点)。我也尝试尽可能多地调试这个问题,但是如果我应该提供其他内容,请告诉我,以便下次遇到麻烦时可以使用这些工具。
一个非常简单的算法,可以用来分解你正在使用的(大)数字是Pollard的Rho算法。
为了简洁起见,我将省略数学解释,但您可以在维基百科文章中找到详细信息。
unisgned long long GCD(unisgned long long x, unisgned long long y)
{
while (y != 0)
{
unsigned long long t = b;
b = a % b;
a = t;
}
return a;
}
unsigned long long f(unsigned long long x, unsigned long long n)
{
return (x * x + 1) % n;
}
unsigned long long PollardRho(unsigned long long n)
{
unsigned long long x = 2, y = 2, d = 1;
while (d == 1)
{
x = f(x);
y = f(f(y));
d = GCD(std::abs(x - y), n);
}
if (d == n)
throw "Failure";
return d;
}
unsigned long long MaxFactor(unsigned long long n)
{
unsigned long long largest = 1;
while (n != 1)
{
unsigned long long factor = PollardRho(n);
largest = std::max(largest, factor);
n /= factor;
}
return largest;
}
注意:我实际上并没有测试C++代码。我在 Mathematica 中对其进行了原型设计,它正确地返回了最大素因数6857
。
为此目的而设计的std::vector<bool>
或std::bitset
,同时考虑到数据密度和快速操作。在常规的布尔数组中,每个元素至少分配一个字节,而不是一个位。
假设600851475143
是一个合数,其最大素因数小于或等于sqrt(600851475143)
或大约775146
。您的筛子不需要比这大。
这个问题(欧拉项目#3)也可以通过简单的暴力分解来解决。在我的台式电脑上,这种方法只需要大约 .002 秒。
- 将数组的地址分配给变量并删除
- vector.resize()中的分配错误
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- Win32编译器选项和内存分配
- 函数中堆分配的效果与缺少堆分配的情况
- 使用动态分配的数组会导致代码分析发出虚假的C6386缓冲区溢出警告
- 多个文件的内存分配错误"在抛出 'std :: bad_alloc' what (): std :: bad_alloc 的实例后终止调用" [C++]
- 获取字符串的长度并将其分配给数组
- 将地址分配给本地指针后,公共对象的变量将消失
- 递归模板化函数不能分配给具有常量限定类型"const tt &"的变量"state"
- 有没有一种方法可以使用placement new将堆叠对象分配给分配的内存
- 我在二维向量中是否正确分配了内存
- 正在尝试重载二进制搜索树分配运算符
- GlobalAlloc而不是其他分配方法
- 自定义先决条件对移动分配运算符有效吗
- 我可以重新分配/覆盖std::字符串吗
- 在c++中使用动态分配的问题
- 当一个新对象被分配到它的地址时,对象是否必须被销毁
- 为什么我可以使用比分配的内存更多的内存
- 组件对象模型 (COM):IMalloc::Alloc 在哪里分配内存?