【问题标题】:Segmentation fault (core dumped) for a C code [closed]C代码的分段错误(核心转储)[关闭]
【发布时间】:2016-09-08 06:38:17
【问题描述】:

我在运行 C 代码时遇到错误,该代码将计数转换为卫星数据的亮度温度。它给了我分段错误。我在这里粘贴我的代码。任何人都可以建议我代码的问题所在。

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

#define N150 150

int main(int argc, char *argv[]){
  int   lon_tl=80,  lat_tl=60;
  int   lon_br=200, lat_br=-60;
  float lon_inc=0.04;
  float lat_inc=0.04;

  FILE  *fp;
  char  outputfilename[N150];
  float tmp_NX, tmp_NY;
  int   i, j, k, nk, NX, NY, tmp_count, count[N150];
  short *data_all;
  float *dt, tmp_tbb, tbb[N150];

  if(argc!=2){
     fprintf(stderr,"Usage: geoss2bt.c inputfilename1\n");
     fprintf(stderr," e.g.: ./geoss2bt IMG_DK01IR1_200705010030.geoss\n");
     exit(1);
  }
  tmp_NX=(lon_br-lon_tl)/lon_inc;  tmp_NY=(lat_tl-lat_br)/lat_inc;
  NX=(int)(tmp_NX);  NY=(int)(tmp_NY);
  data_all=(short*)malloc(2*NY*NX);
  dt=(float*)malloc(4*NY*NX);
  for(i=0;i<NY*NX;i++){
     data_all[i]=-999;
     dt[i]=-999.;
  }

  if((fp=fopen(argv[1],"r"))==NULL){
     fprintf(stderr,"*** input file (%s) cannot open ***\n",argv[1]);
     exit(1);
  }
  fread(data_all,sizeof(short),NY*NX,fp);
  fclose(fp);

  if((fp=fopen("tbbtable.txt","r"))==NULL){
     fprintf(stderr,"*** TBB table (tbbtable.txt) cannot open ***\n");
     exit(1);
  }
  k=0;
  while(!feof(fp)){
     fscanf(fp,"%d %f",&tmp_count, &tmp_tbb);
     count[k]=tmp_count;  tbb[k]=tmp_tbb;
     k++;
  }
  nk=k;
  fclose(fp);

  for(i=0;i<NY;i++){
  for(j=0;j<NX;j++){
     if(data_all[NX*i+j]<count[0]){ dt[NX*i+j]=-999.; }
     else if(data_all[NX*i+j]==count[0]) { dt[NX*i+j]=tbb[0]; }
     else{
        for(k=1;k<nk;k++){
           if(data_all[NX*i+j]<=count[k]){
            dt[NX*i+j]=tbb[k]-(tbb[k]-tbb[k-1])*(count[k]-data_all[NX*i+j])/(count[k]-count[k-1]);
            goto LOOP;
           }
        }
     }
     LOOP:;
  }
  }

  sprintf(outputfilename,"tbb_%s",argv[1]);
  fp = fopen(outputfilename,"w");
  fwrite(dt,sizeof(float),NX*NY,fp);
  fclose(fp);

  free(data_all);  free(dt);
  return 0;
}

【问题讨论】:

  • 输入是什么?
  • 在寻求帮助之前,您实际上是否自己完成了任何基本调试。就像使用调试器和/或调试打印语句来跟踪程序的执行一样。调试器会准确地告诉你是哪一行导致了初学者的 seg 错误。
  • 你是否故意让你的代码难以理解,因为缩进很差,没有 cmets,一行中有多个语句,标记之间没有空格,变量名不明显和太相似等等?
  • @kaylum 当我在这里粘贴我的代码时,它要求我输入 4 个字符空间。我认为那里的缩进出了问题。这是我在这里的第一个问题,请原谅错误。
  • 从文件中读取的whileloop 不会检查缓冲区溢出 (k &gt;= 150)。

标签: c segmentation-fault


【解决方案1】:

在代码的最后,你写:

fopen(outputfilename,"w");
fwrite(dt,sizeof(float),NX*NY,fp);
fclose(fp);

我认为应该是:

fp = fopen(outputfilename,"w");
fwrite(dt,sizeof(float),NX*NY,fp);
fclose(fp);

但是,你的代码很容易出错:

不要犹豫,评论你的代码,它永远不会没用。

【讨论】:

  • 我按照你的建议修改了,但是还是有分段错误信息。
  • 感谢您指出 feof 的错误使用。我将 while 循环命令修改为 while(fgets(buf, 100, fp) != NULL)。它现在运行良好。
【解决方案2】:

我不确定,但也许这也可能导致问题。根据我的计算,你分配的是这两行,大约 54MB 的内存:

data_all=(short*)malloc(2*NY*NX);
dt=(float*)malloc(4*NY*NX); 

堆栈溢出可能会导致分段错误,请确保将堆栈大小设置得足够大。

Why stack overflow causes segmentation fault instead of stack overflow in Linux?

【讨论】:

  • 感谢您的回复。关于如何增加堆栈大小的任何建议。
  • malloc 通常从 heap 分配内存。在现代操作系统(Linux/Windows/OS X)中,在堆上分配 54 Mb 应该不是问题,除非您减小了允许的最大进程大小。
猜你喜欢
  • 2021-11-13
  • 1970-01-01
  • 2013-04-28
  • 1970-01-01
  • 2018-04-03
  • 1970-01-01
  • 1970-01-01
  • 2012-11-20
  • 1970-01-01
相关资源
最近更新 更多