【问题标题】:How to debug why my C code causes a segmentation fault? [closed]如何调试我的 C 代码导致分段错误的原因? [关闭]
【发布时间】:2014-10-30 12:52:19
【问题描述】:

下面的代码获取一个大小为 windowSize 的窗口,并在每次迭代中将窗口移动一些 shiftSize 样本。

我进行了不寻常的“printf()”调试,发现代码在分段错误时出错。谁能告诉我错误是什么?

代码:

 #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
    #include <tgmath.h>
    int main ()
    {

        FILE *fp, *in   ;

        in = fopen ("controlFile.txt", "r");

        if (in == NULL) {
          fprintf(stderr, "Can't open input file in.list!\n");
          exit(1);
        }

        char equalTo, commandType[20];
        int commands[3]; int i=0;

        while (!feof(in)){

                fscanf(in, "%s %c %d\n", commandType, &equalTo, &commands[i]);
                printf("%s %c %d\n", commandType, equalTo, commands[i]);
                i++;
        }

        fclose(in);

        fp = fopen ("OriginalData.txt", "r");

        if (fp == NULL) {
          fprintf(stderr, "Can't open input file in.list!\n");
          exit(1);
        }

    //Note: time is milliseconds. Therefore, multiplying factor is 1000
        int mulFactor =1000;

        int samplesPerSecond = commands[0];

        int windowSize = floor((commands[1]*mulFactor)/samplesPerSecond); //This will be our array size or rank for cuda Program

        int shiftSize = floor ((commands[2]*mulFactor)/samplesPerSecond);

        int fileCounter  = 0, breakFlag=0;
        int allocationSize = 100;
        float *values, test;

        values = (float*) malloc (100*sizeof(float));

        if (values==NULL)
                {
                        printf("Error allocating memory!");
                        exit (1);
                }
        int localCounter = 0;
        int arrayCounter = 0;
        int copyCounter = windowSize - shiftSize;
//      printf("SamplesPerSecond: %d\n windowSize: %d\n shiftSize: %d\n copyCounter: %d\n", samplesPerSecond, windowSize, shiftSize, copyCounter);
        int temp;
        float* check;
        while (!feof(fp)){
                localCounter = 0;
                if (fileCounter==0){
                        while (!feof (fp) && localCounter!=windowSize){
                                fscanf(fp, "%f", &values[arrayCounter]);
                                printf("%f\n", values[arrayCounter]);
                                localCounter++;
                                fileCounter++;
                                                      arrayCounter++;
                                //printf("%f\n", values[arrayCounter]);
                                if (sizeof(values)/sizeof(float)==arrayCounter-1){
                                        values = (float*)realloc (values, (size_t)(allocationSize*sizeof(float)));
                                        if (values==NULL){
                                                printf("Cannot allocate memory\n");
                                                exit(1);
                                        }
                                }
                        }
                }
                else{
                        temp = copyCounter;
                //      printf("Here\n"); 
                        while (temp!=0 && !feof(fp)){
                                  //if (feof(fp)) {printf ("Been Here\n");breakFlag = 1; break;}
                                values[arrayCounter] = values [arrayCounter-copyCounter];
                                printf("%f\n", values[arrayCounter]);
                                temp--;
                                arrayCounter++;
                                localCounter++;
                                if (sizeof(values)/sizeof(float)==arrayCounter-1){
                                        values= (float*)realloc (values, allocationSize*sizeof(float));
                                        if (values==NULL){
                                                printf("Cannot allocate memory\n");
                                                exit(1);
                                        }
                                }

                        }
                         while (localCounter!=windowSize && !feof(fp)){
                                fscanf(fp, "%f", &values[arrayCounter]);
                                printf("%f\n", values[arrayCounter]);
                                localCounter++;
                                fileCounter++;
                                               arrayCounter++;
                                if (sizeof(values)/sizeof(float)==arrayCounter-1){
                                       values= (float*)realloc (values, allocationSize*sizeof(float));
                                        if (values==NULL){
                                                printf("Cannot allocate memory\n");
                                                exit(1);
                                        }
                        }
                        }
                }
        }
        fclose(fp);
        //int numOfFrames = floor((fileCounter-1)/shiftSize);  //Count the number of lines when fp is increasing
        //int j;
/*      for(j=0; j<(sizeof(values)/sizeof(float)); j++){
                printf ("%f\n", values[j]);
        }
*/
        return 0;
}

【问题讨论】:

  • 嗯...您不能将代码剔除到显示错误所需的最低限度吗?我真的不想经历所有这些来找到出错的地方......
  • 在执行 i++ 时检查 int commands[i],因为定义 int commands[3];
  • 在进行 I/O 之前不要检查feof(),它不会那样工作。
  • Sizeof 和你想的不一样。if (sizeof(values)/sizeof(float)... 完全错误
  • sizeof (values) 表示:指向浮点数的指针的大小(values 是指向浮点数的指针)sizeof (float) 是浮点数的大小。根据您的平台,将它们分开可能会产生 1 或 2。将结果与arrayCounter-1 进行比较通常会得出not equal 的结果。 (但这将取决于先前分配的 values 指向的对象的大小,这显然是您想要的)

标签: c file heap-memory stack-memory fclose


【解决方案1】:

1) 你先检查feof()然后检查fscanf()然后不检查它的返回值(或者重新检查feof()至少。(在fscanf() 调用之前,您可能就在文件末尾,或者配置文件可能格式错误,但您的代码不会检测到这一点。)

2) 你的索引范围检查(和各种realloc()s)看起来很狡猾。但是我绝对没有机会对您的代码进行运行时分析,尤其是因为我没有输入文件示例。

做一些Machete Debugging...

编辑: 在 joop 的评论将我指向您的 realloc()(以及围绕它的 if 声明)的细则之后,没有评论解释您希望它如何工作出来,我会说你在那里调用了未定义的行为。

【讨论】:

  • 如果我提供样本输入,您能帮我吗?我是一名 C 业余程序员,我非常渴望实现这一目标。
  • @DeveloperbyBlood:除了“需要样本输入”之外,在这个线程中已经给出了很多好的,不,重要的建议。例如,我发布的链接应该给我们上一堂宝贵的课。我建议你从“希望这个程序发生”(这对于初学者来说是一个不好的前提)退后一步,花点时间熟悉这门语言、它的陷阱和它的良好实践。您发布的代码基本上是 FUBAR,需要重新思考和重写。您可以耐心地自己解决这个问题,并在此过程中成为更好的程序员。
  • 所以,我回去阅读了 realloc()、sizeof() 函数的语法、返回类型和用法,并意识到我错在哪里。感谢 DevSolar 的激励和 @joop 强调 关键 错误 - 这个错误让我学到了很多东西。
猜你喜欢
  • 1970-01-01
  • 2014-08-29
  • 2020-11-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-14
相关资源
最近更新 更多