2011-04-28 44 views
1

我有一个内存分配问题。但我不知道问题出在哪里异常:std :: bad_alloc在循环中的内存位置

在第55次迭代运行下面的循环时出现错误。在那之下,代码给了我我想要的。

的代码段,其中的错误发生(整个代码过长):

while(k<75){ 

     domainz1.getVerticalBoundaryBegin(xz1,e1,row); 
     domainz2.getVerticalBoundaryBegin(xz2,e2,row); 
     domainz3.getVerticalBoundaryBegin(xz3,e3,row); 
     domainz4.getVerticalBoundaryBegin(xz4,e4,row); 
     domainz5.getVerticalBoundaryBegin(xz5,e5,row); 
     domainz6.getVerticalBoundaryBegin(xz6,e6,row); 


     domaine1.drichletFunctionalUpdateVertical(Ae1,be1,e1,ydimDom); 
     domaine2.drichletFunctionalUpdateVertical(Ae2,be2,e1,1); 
     domaine2.drichletFunctionalUpdateVertical(Ae2,be2,e2,ydimDom); 
     domaine3.drichletFunctionalUpdateVertical(Ae3,be3,e2,1); 
     domaine3.drichletFunctionalUpdateVertical(Ae3,be3,e3,ydimDom); 
     domaine4.drichletFunctionalUpdateVertical(Ae4,be4,e3,1); 
     domaine4.drichletFunctionalUpdateVertical(Ae4,be4,e4,ydimDom); 
     domaine5.drichletFunctionalUpdateVertical(Ae5,be5,e4,1); 
     domaine5.drichletFunctionalUpdateVertical(Ae5,be5,e5,ydimDom); 
     domaine6.drichletFunctionalUpdateVertical(Ae6,be6,e5,1); 
     domaine6.drichletFunctionalUpdateVertical(Ae6,be6,e6,ydimDom); 
     domaine7.drichletFunctionalUpdateVertical(Ae7,be7,e6,1); 

     gmressolver2d(Ae1,xe1,be1,KrylovDim,xdim,ydimDom,COP,twoDimStencil,0,1); 
     gmressolver2d(Ae2,xe2,be2,KrylovDim,xdim,ydimDom,COP,twoDimStencil,0,1); 
     gmressolver2d(Ae3,xe3,be3,KrylovDim,xdim,ydimDom,COP,twoDimStencil,0,1); 
     gmressolver2d(Ae4,xe4,be4,KrylovDim,xdim,ydimDom,COP,twoDimStencil,0,1); 
     gmressolver2d(Ae5,xe5,be5,KrylovDim,xdim,ydimDom,COP,twoDimStencil,0,1); 
     gmressolver2d(Ae6,xe6,be6,KrylovDim,xdim,ydimDom,COP,twoDimStencil,0,1); 
     gmressolver2d(Ae7,xe7,be7,KrylovDim,xdim,ydimDom,COP,twoDimStencil,0,1); 

     //******************************************************************* 
     domaine1.getVerticalBoundaryBegin(xe1,z1,row); 
     domaine2.getVerticalBoundaryBegin(xe2,z2,row); 
     domaine3.getVerticalBoundaryBegin(xe3,z3,row); 
     domaine4.getVerticalBoundaryBegin(xe4,z4,row); 
     domaine5.getVerticalBoundaryBegin(xe5,z5,row); 
     domaine6.getVerticalBoundaryBegin(xe6,z6,row); 
     domaine7.getVerticalBoundaryBegin(xe7,z7,row); 


     domainz1.drichletFunctionalUpdateVertical(Az1,bz1,z1,1); 
     domainz1.drichletFunctionalUpdateVertical(Az1,bz1,z2,ydimDom); 
     domainz2.drichletFunctionalUpdateVertical(Az2,bz2,z2,1); 
     domainz2.drichletFunctionalUpdateVertical(Az2,bz2,z3,ydimDom); 
     domainz3.drichletFunctionalUpdateVertical(Az3,bz3,z3,1); 
     domainz3.drichletFunctionalUpdateVertical(Az3,bz3,z4,ydimDom); 
     domainz4.drichletFunctionalUpdateVertical(Az4,bz4,z4,1); 
     domainz4.drichletFunctionalUpdateVertical(Az4,bz4,z5,ydimDom); 
     domainz5.drichletFunctionalUpdateVertical(Az5,bz5,z5,1); 
     domainz5.drichletFunctionalUpdateVertical(Az5,bz5,z6,ydimDom); 
     domainz6.drichletFunctionalUpdateVertical(Az6,bz6,z6,1); 
     domainz6.drichletFunctionalUpdateVertical(Az6,bz6,z7,ydimDom); 

     gmressolver2d(Az1,xz1,bz1,KrylovDim,xdim,ydimDom,COP,twoDimStencil,0,1); 
     gmressolver2d(Az2,xz2,bz2,KrylovDim,xdim,ydimDom,COP,twoDimStencil,0,1); 
     gmressolver2d(Az3,xz3,bz3,KrylovDim,xdim,ydimDom,COP,twoDimStencil,0,1); 
     gmressolver2d(Az4,xz4,bz4,KrylovDim,xdim,ydimDom,COP,twoDimStencil,0,1); 
     gmressolver2d(Az5,xz5,bz5,KrylovDim,xdim,ydimDom,COP,twoDimStencil,0,1); 
     gmressolver2d(Az6,xz6,bz6,KrylovDim,xdim,ydimDom,COP,twoDimStencil,0,1); 


     k++; 

     printf("%d iterations done\n",k); 
    } 

在这里,在括号内几乎所有的条款都列。

AE1,AE2,AZ1,AZ2,.....是2D阵列71x11

XE1,XZ1,BZ1,BE1,E1,E2,Z1,Z2,.........是一维数组(71x11)。

这些类运算符基本上在这些数组之间传输数据。这是一个科学的代码,gmressolver2d解决了每次迭代中的新问题。

这一点是我的内存分配总是随机增加,我不知道该怎么做,以防止这种情况。

此致敬礼, 埃姆雷。

编辑:我的数组分配。

template <typename T> 
T ****AllocateDynamic4DArray(int nRows, int nCols, int nSlice, int kSlice) 
{ 
     T ****dynamicArray; 

     dynamicArray = new T***[nRows]; 
     for(int i = 0 ; i < nRows ; i++){ 
     dynamicArray[i] = new T**[nCols]; 
     for (int j=0; j<nCols;j++){ 
      dynamicArray[i][j] = new T*[nSlice]; 
      for (int k=0; k<nSlice; k++){ 
       dynamicArray[i][j][k] = new T[kSlice]; 
       for(int l=0;l<kSlice;l++){ 
        dynamicArray[i][j][k][l] = 0; 
       } 
      } 
     } 
     } 
     return dynamicArray; 
} 
template <typename T> 
T ***AllocateDynamic3DArray(int nRows, int nCols, int nSlice){ 
     T ***dynamicArray; 

     dynamicArray = new T**[nRows]; 
     for(int i = 0 ; i < nRows ; i++){ 
     dynamicArray[i] = new T*[nCols]; 
     for (int j=0; j<nCols;j++){ 
      dynamicArray[i][j] = new T[nSlice]; 
      for (int k=0; k<nSlice; k++){ 
        dynamicArray[i][j][k]= 0; 
       } 
      } 
     } 
     return dynamicArray; 
} 
template <typename T> 
T **AllocateDynamic2DArray(int nRows, int nCols){ 
     T **dynamicArray; 

     dynamicArray = new T*[nRows]; 
     for(int i = 0 ; i < nRows ; i++){ 
     dynamicArray[i] = new T[nCols]; 
     for (int j=0; j<nCols;j++){ 
       dynamicArray[i][j]= 0; 
      } 
     } 
     return dynamicArray; 
} 
template <typename T> 
T *AllocateDynamicVector(int nRows){ 
     T *dynamicArray; 

     dynamicArray = new T[nRows]; 
     for(int i = 0 ; i < nRows ; i++){ 
      dynamicArray[i]= 0; 
     } 
     return dynamicArray; 
} 
+0

循环中没有分配内存。问题出现在循环中执行的某个函数中。请显示这些功能的定义。 – Oswald 2011-04-28 17:46:10

+0

这很难回答。你的问题基本上是你的内存不足,但是我们不知道在哪里分配了内存,因为你的任何函数都可以这样做。你能举一个有效的例子吗? – 2011-04-28 17:47:25

+0

系统中有多少RAM?通常,当内存不足时,该“异常”将由'new'引发。对于每个循环,通常分配多少内存?当你重复循环时,是否需要堆中的每个生成的项目都保留在先前循环迭代的内存中? – Jason 2011-04-28 17:48:22

回答

2

在调试器中运行该程序,并设置调试器,以便在抛出异常时中断程序。一旦程序暂停(由于例外),使用调试器的调用堆栈功能来查看异常被抛出的上下文。

我想给你更详细的说明,但你不指定你使用的平台/编译器。


how-to介绍如何设置Visual Studio中对任何异常破裂。

这个how-to描述了如何使用调用堆栈。

+0

我使用visual studio 2010最终版,感谢您的建议 – 2011-04-28 17:56:43

+0

@Emre:查看更新后的答案。 – 2011-04-28 18:04:38

+0

谢谢你,现在我知道问题在哪里。我仍然有点困惑。这是另一个问题 - 但不能将多维数组“A”删除为“delete [] A”,还是必须为此设置循环? – 2011-04-28 18:12:04

1

使用UMDH.EXE把应用程序的堆使用的快照连续环路前,然后比较这两个快照。如果设置得当,可以看到过渡期间所有异步行为的调用堆栈。

+0

+1不知道这个工具。 – 2011-04-28 18:20:12

1

当以您分配数组的方式删除数组时,对delete [] array_name的单个调用将不起作用,因为数组维度中的每个索引都是新分配的指针“子数组”。所以你将不得不遍历每一行/列/切片/等。并在构成数组索引的指针数组上调用delete []。例如,要释放一个3D阵列,您必须执行如下操作:

for (int i=0; i < column_size; i++) 
{ 
    for (int j=0; j < slice_size; j++) 
    { 
     delete [] array_name[i][j]; 
    } 

    delete [] array_name[i]; 
} 

delete [] array_name; 
+0

谢谢杰森。我正在寻找这个=) – 2011-04-28 19:06:03

相关问题