【问题标题】:Array declaration: C Segmentation fault数组声明:C 分段错误
【发布时间】:2016-07-18 18:34:09
【问题描述】:

我正在尝试在C上写一个数组(2x20000)。测试代码是:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>  

double test( int smod )
{
//
// test subroutine
//
double  vect_fma[2][20000];
int i;

// write on file //
FILE *f = fopen("file.txt", "w");
///////////////////

   for( i = 1; i < 20001; i = i + 1 ){     
    // allocate the vector for the fma analysis
    vect_fma[1][i] = i*smod;
    vect_fma[2][i] = i*smod;
    if ( i%smod == 0 ) 
    fprintf(f, "%f %f %f  \n", 1.0*i, vect_fma[1][i],vect_fma[2][i] );   
}    
    fclose(f);
    return 0;
}  


int smod;
void main()
{  
  smod  = 10; // every 10 print the output 
    test(smod);    // call the function  
}

我用gcc test.c -lm -o test 编译了代码,我收到了Segmentation fault (core dumped)

就我是 C 的新手而言,我知道“the compiler tries to store it on the stack”和解决方案可能是链接页面中提供的解决方案....但是如果比较,该解决方案看起来很奇怪(而且理解起来很复杂)使用更简单的数组 real(8), dimension(n:m) :: vect_fma 的 fortran 声明,我可以将其放入子例程或函数中而不会出现问题。 也许我在代码中写的声明类似于 fortran real(8), dimension(n,m),allocatable :: vect_fma one ?

所以问题是,在 C 中是否存在一种更简单的方法来在函数内声明数组? 非常感谢大家。

【问题讨论】:

  • 对于堆栈来说可能太大 - 请改用堆
  • @EdHeal 类似2d_array = (int *)malloc(sizeof(int)*N*M); ?
  • 您是否在编译期间(这是您的答案所暗示的)或执行期间收到分段错误?
  • C 数组总是基于 0 的索引,而不是基于 1 的索引。 vect_fma[2] 在数组边界之外,vect_fma[1][i]i == 20000 时也是如此。
  • @CorbinMc 在执行期间

标签: c arrays file-io


【解决方案1】:

您在多个地方都有越界访问,这是未定义的行为。 在 C 中,数组索引的范围是从 0N-1,而不是从 1N。这意味着,将循环部分重写为:

   for( i = 0; i < 20000; i = i + 1 ){     
    // allocate the vector for the fma analysis
    vect_fma[0][i] = i*smod;
    vect_fma[1][i] = i*smod;
    if ( i%smod == 0 ) 
       fprintf(f, "%f %f %f  \n", 1.0*i, vect_fma[0][i],vect_fma[1][i] );   
}    

2x20000 double 可能对于您系统上的堆栈大小来说太大了,您最好先修复未定义的行为 看看问题是否消失。

【讨论】:

  • 感谢您的回答,整数是正确的,并感谢发布的示例。我与从 1 到 20000 开始的 fortran 混在一起,这意味着我有 20000 个元素,而在 C 中我必须从 0 到 20000 开始。
  • 0 到 19999 不是 20000,因为是 &lt; 20000
【解决方案2】:

问题在于您的 for 循环。您应该从i=0 的迭代开始,并以i=19999 的迭代结束。您的代码以i=1 的迭代开始,以i=20000 的迭代结束。

问题是您的数组中没有第 20000 个元素,只有第 19999 个元素(索引为零)。当您访问第 20000 个元素时,您访问的系统内存从未分配给您的程序,这会导致分段错误。

修复你的 for 循环,你应该会很好。

【讨论】:

    猜你喜欢
    • 2012-12-31
    • 1970-01-01
    • 2011-12-27
    • 2015-07-14
    • 2021-10-18
    • 1970-01-01
    • 2016-12-05
    • 2019-09-03
    • 1970-01-01
    相关资源
    最近更新 更多