尝试在C程序中声明5D数组时出现分段错误

时间:2019-04-12 17:55:10

标签: c memory fortran segmentation-fault

我正在将程序从fortran77转换为C编程语言,在fortran程序中,声明了一个5D数组,如下所示,并且代码可以很好地编译和执行。但是,当我将相同的代码转换为具有相同值的C时,C代码会编译,但会出现分段错误。

如果此问题是由于两种语言之间多维数组内存分配的标准布局不同而引起的,则我在用C声明数组时尝试了所有维组合,并且在所有情况下都给出了“分段错误”。

我也厌倦了下面显示的'calloc'技术,它可以工作,但是我不知道如何为全局声明的数组赋值。

注意:分段错误是在声明步骤(即程序在此处停止)

所以基本上我的问题是: -为什么它不能在fortran中工作,而不能在C中工​​作? -如何用C解决这个问题?

 ! Fortran77 Code
  parameter (i2maxbin=38)     
  parameter (imaxbin=20)       
  parameter (Nid=10)      
  real*8 dNdpt(Nid,i2maxbin,imaxbin,imaxbin,imaxbin)

 /* C Code */
  const int i2maxbin = 38;
  const int imaxbin = 20;
  const int nID = 10;
  double dNdpt[nID][i2maxbin][imaxbin][imaxbin][imaxbin];

 /* Declaring using calloc */
double (*dNdpt)[nID][i2maxbin][imaxbin][imaxbin][imaxbin] = 
calloc(sizeof(*dNdpt), 38);

for(int i = 0; i < nID; i++)
{
    for(int j = 0; j < i2maxbin; j++)
    {
        dNdpt[i][j][0][0][0] = 12.22673423;
    }        
}

When executing it gives me this error

error: assignment to expression with array type
         dNdpt[i][j][0][0][0] = 12.22673423;
                              ^

3 个答案:

答案 0 :(得分:0)

C和C ++中的堆栈大小非常有限,通常允许最大1e5大小的1D数组,如果我们假设“ double”大小为8字节,则表示最大内存为8 * 1e5字节。

现在,让我们看一下您的5D数组,它正在尝试分配10 * 38 * 20 * 20 * 20 = 3,040,000个“双”单元,将其转换为内存后,它的大小为24,320,000字节,远高于分配的堆栈大小。 C或C ++。 这就是为什么您遇到SEG-FAULT的原因。

您可以尝试以这种方式全局初始化数组,即为它分配的堆内存通常大于堆栈内存,即使那样最大的最大大小也被限制为8 * 7 * 1e5字节(取决于您的计算机)。< / p>

答案 1 :(得分:0)

您可以通过在堆而不是堆栈上创建数组来解决该问题。

static

然后通过计算索引来跟踪您在此巨大数组中的位置

一个简单的例子:

double* dNdpt = malloc(sizeof(double)*nID*i2maxbin*imaxbin*imaxbin*imaxbin);

答案 2 :(得分:0)

以下建议的代码:

  1. 将数组放置在文件范围而不是堆栈中
  2. 干净地编译
  3. 避免使用动态内存分配/释放
  4. 干净地运行并退出而不会崩溃
  5. 避免使用VLA

现在是建议的代码:

#define i2maxbin  38
#define imaxbin   20
#define nID       10



double dNptr[nID][i2maxbin][imaxbin][imaxbin][imaxbin];


int main( void )
{
    for(int i = 0; i < nID; i++)
    {
        for(int j = 0; j < i2maxbin; j++)
        {
            dNptr[i][j][0][0][0] = 12.22673423;
        }
    }
}