0

在运行以下脚本时,出现分段错误。输出由“here 5a”组成。但除此之外什么都没有。关于可能出现问题的任何建议?

if(model==1) 
  fptr3=fopen("poisson.pro","r");
if(model==2)
  fptr3=fopen("jtt.pro","r");
if(model==3)
  fptr3=fopen("estimate.pro","r"); 

printf ("here 5a\n");
for (i=0;i<20;i++) 
  fscanf(fptr3,"%lf", &freq[i]);
printf ("here 5ai\n");

for (i=0;i<20;i++) 
{
  printf ("here 5b\n");
  for (j=0;j<20;j++) 
  {
    printf ("here 5c\n");
    fscanf(fptr3,"%lf", &prob[i][j]);
    if(model==3) 
      prob[i][j]=prob[i][j]/10000.0;
  }
}

更新

double freq[20], prob[20][20];
4

7 回答 7

2

这是 C# 吗????哇,别开玩笑了,你遇到了段错误......你知道返回码是什么吗???在寻求这种帮助之前,你真的需要改进你的代码......这真的是不可读,丑陋的代码......开始为你的文件指针添加一些检查

    if(1==model)
{
 fptr3=fopen("poisson.pro","r");
 if(null == fptr3)
{
  perror("Fopen failed");
}

...

于 2009-07-27T02:32:07.413 回答
2

valgrind是 C 中段错误的主权补救措施。它在段错误之前发现错误并准确告诉你你做错了什么。为了获得最大利益,请在打开调试符号的情况下进行编译。

于 2009-07-27T02:55:00.247 回答
2

您确定调用了此代码并且“模型”是 1、2 或 3?如果没有,fptr3 就不会被设置,所以如果你试图用它做任何事情,你就会遇到麻烦。

试试这个?:

void modeltest (int model) 
{
    FILE *fptr3 = NULL;
    int i = 0;
    int j = 0;
    double freq[20], prob[20][20];

    if(model==1) fptr3=fopen("poisson.pro","r");
    if(model==2) fptr3=fopen("jtt.pro","r");
    if(model==3) fptr3=fopen("estimate.pro","r");

    printf ("here 5a\n");
    if (fptr3 != NULL) {
        for (i=0;i<20;i++) fscanf(fptr3,"%lf", &freq[i]);
        printf ("here 5ai\n");
        for (i=0;i<20;i++) {
            printf ("here 5b\n");
            for (j=0;j<20;j++) {
                printf ("here 5c\n");
                fscanf(fptr3,"%lf", &prob[i][j]);
                if(model==3) prob[i][j]=prob[i][j]/10000.0;
            }
        }
    }
    else {
        printf ("fptr3 is NULL!\n");
    }
}

附加说明。请,请,请考虑一致的括号样式!:)

于 2009-07-27T03:33:43.810 回答
1

我同意丹尼尔,你需要检查你的返回值和指针。

我也同意您需要更好地阻止和格式化您的代码。假设你是唯一一个读过它的人,在几个星期内,即使你已经忘记了很多,你将无法继续阅读它。

对于 Matthews 点,您可以尝试删除以该行开头的所有内容:

printf ("here 5ai\n");

当然,只有在检查文件指针后才可以解决这个问题。

另一个疯狂的想法是使用调试器逐步完成它。我知道当您拥有像 printf 语句这样出色的调试选项时,很难使用调试器,但有时调试器可以节省大量时间(例如,当您不断遇到段错误时)。此外,学习如何在您正在开发的平台上使用调试器是将优秀编码人员与普通黑客包区分开来的事情之一。(仅供参考,您甚至可以尝试在调试器中查看您的核心,也许可以确切地看到问题出在哪里。(提示:如果您没有核心文件,请尝试“man ulimit”。))

如果您要坚持使用 printf 作为您唯一的调试方式,请在每次使用后立即调用 flush。

于 2009-07-27T03:15:57.233 回答
0

频率定义是什么?概率定义为什么?

第一个 for 循环是否意味着只为频率运行 fscanf?还是应该包含整个街区?

编辑:基本原理 - 如果你看到的只是 5a,那么它在 fscanf on freq 中出现故障。您可能为频率分配了太少的空间,或者使用了不正确的类型。

于 2009-07-27T02:31:16.370 回答
0
  1. 检查返回代码并在需要时使用 perror() 打印文件的错误代码(请参阅丹尼尔答案)。使用 FILE * 将 fscanf() 调用为 NULL,肯定会出现段错误。

  2. 当您指定 %lf 时,freq 必须是一个至少包含 20 个双精度数的数组,而不仅仅是浮点数。参见 man frintf()。

  3. 使用调试器而不是 printf()。

于 2009-07-27T02:56:09.730 回答
0

您应该发布正在打开的任何文件的开头的内容,因为它在 fscanf 中崩溃。该文件不存在,或者在与您尝试解析它的方式相反时它的格式不正确。

于 2009-07-27T03:23:01.960 回答