C ++程序因大型阵列而崩溃,即使它在堆上

时间:2013-02-07 06:03:59

标签: c++ arrays memory-management crash heap

我正在为三个非常大的数组(N = 990000001)分配内存。我知道你必须在堆上分配它,因为它太大了,但即使我这样做,程序仍然会崩溃。我错误地分配它还是我的电脑根本没有足够的内存(我应该有足够的)?另一件可能是问题的是我以某种方式错误地分配了我的记忆。现在我分配内存的方式在N很小时完全正常。任何帮助表示赞赏。

int main()
{
double *Ue = new double[N];
double *U = new double[N];
double *X = new double[N];
for (int i = 0; i < N; i++)
{
    X[i] = X0 + dx*i;
    Ue[i] = U0/pow((X0*X[i]),alpha);
}

//Declare Variables
double K1;double K2; double K3; double K4;

//Set Initial Condition
U[0] = U0;
for (int i = 0; i < N-1; i++)
{
    K1 = deriv(U[i],X[i]);
    K2 = deriv(U[i]+0.5*dx*K1,X[i]+0.5*dx);
    K3 = deriv(U[i]+0.5*dx*K2,X[i]+0.5*dx);
    K4 = deriv(U[i]+dx*K3,X[i+1]);
    U[i+1] = U[i] + dx/6*(K1 + 2*K2 + 2*K3 + K4);
}

return 0;
}

2 个答案:

答案 0 :(得分:3)

您的程序分配并使用大约24 GB的内存。

如果你是一个32位进程的程序,这将抛出std::bad_alloc,你的程序将正常退出。 (理论上你的工具链中可能存在溢出错误,但我认为这不太可能。)

如果你是64位进程的程序,你可能会受到OOM杀手的阻碍,你的程序会不合时宜地退出。除非您在组合RAM +交换中有24 GB,否则您可能会以磁盘的速度进行转换。 (如果你实际上有 24 GB的RAM,那么它可能不会崩溃,所以我们可以将其排除在外。)如果禁用过度使用,那么你将获得std::bad_alloc而不是OOM杀手。 (这一段是特定于Linux的,虽然其他内核类似。)

解决方案:使用更少内存或购买更多内存。

答案 1 :(得分:0)

如果在Windows上,您可能会发现有用的此信息Memory Limits for Applications on Windows -

  

请注意,静态和堆栈数据的限制在两者中都是相同的   32位和64位变体。这是由于Windows的格式   可移植可执行文件(PE)文件类型,用于描述EXE和   链接器列出的DLL。它具有用于图像部分的32位字段   偏移量和长度并没有扩展为64位变体   视窗。与32位Windows一样,静态数据和堆栈共享相同   首先是2GB的地址空间。

然后,唯一真正的改进 -

  

动态数据 - 这是在程序期间分配的内存   执行。在C或C ++中,通常使用mallocnew

     

64位

     
      
  • 静态数据2Gb

  •   
  • 动态数据8Tb

  •   
  • 堆叠数据1GB   (堆栈大小由链接器设置,默认值为1MB。这可以是   使用Linker属性System&gt;增加堆栈储备规模)

  •   

单个阵列的分配&#34;应该能够分配与操作系统愿意处理的一样大的&#34; (即受RAM和碎片限制)。