3

我无法让一些 C 代码正确运行(如果这个问题很愚蠢,请多多包涵,因为我是 C 新手;另外,所以每个人都很清楚,这是我在运行时遇到问题的代码。我唯一的部分'已经写的是空文件句柄检查)。基本上,我的程序在fclose. 先上代码:

在文件的顶部:

int *label;

具体方法:

void load_dat ()
{
  int    i, j, t, k;
  FILE   *in;
  char   t_file[16];

  printf ("\nName of Raw Data File > ");
  scanf ("%s", t_file);
  in = fopen (t_file, "r");
  if (in == NULL){
    perror("fopen error");
  }
 fscanf (in, "%d %d %d", &num_pats, &a_length, &b_length);

 dpt = (float **) malloc (sizeof(float *)*num_pats);

 for (k=0; k<num_pats; k++){
    dpt[k] = (float *) malloc (sizeof(float)*(a_length+b_length));
 }

 label = (int *) malloc (sizeof(int)*num_pats);

  for (i=0; i<num_pats; i++)
  {
      for (j=0; j<a_length; j++)
      {
        fscanf (in, "%f", &dpt[i][j]);
      }

  fscanf (in, "%d", &label[i]);


  if (label[i]<0 || label[i]>3)
    printf ("ERROR: Label corrupted.\n");

    for (t=0; t<b_length; t++){
        dpt[i][t+a_length] = 0.0;
        dpt[i][label[i]+a_length] = 1.0;
    }
  }
  fclose (in); 
}      

我的程序错误信息是:Abort trap: 6. 谷歌搜索最终导致了我使用的建议GBD,这给了我:

Program received signal SIGABRT, Aborted.

#0  0x00007fff8c12582a in __kill ()
#1  0x00007fff871a3b6c in __abort ()  
#2  0x00007fff871a0070 in __stack_chk_fail ()
#3  0x000000010000175f in load_dat ()
#4  0x0000000100001baa in main ()
#5  0x00000001000013e4 in start ()

如果我单步执行整个方法,程序不会崩溃,直到我到达最后一行fclose(in)。此外, 的值in在整个程序中保持不变。

搜索与 相关的问题时fclose,我遇到了这个 SO 帖子,这导致我尝试使用Valgrind,其输出(使用--leak-check=yes)是:

==22688== 
==22688== Process terminating with default action of signal 6 (SIGABRT)
==22688==    at 0x2DD82A: __kill (in /usr/lib/system/libsystem_kernel.dylib)
==22688==    by 0x18A06F: __stack_chk_fail (in /usr/lib/system/libsystem_c.dylib)
==22688==    by 0x10000175E: load_dat (in ./dataPre) 
==22688==    by 0x100001BA9: main (in ./dataPre)
==22688== 
==22688== HEAP SUMMARY:
==22688==     in use at exit: 28,781 bytes in 83 blocks
==22688==   total heap usage: 84 allocs, 1 frees, 32,877 bytes allocated
==22688== 
==22688== LEAK SUMMARY:
==22688==    definitely lost: 0 bytes in 0 blocks
==22688==    indirectly lost: 0 bytes in 0 blocks
==22688==      possibly lost: 0 bytes in 0 blocks
==22688==    still reachable: 28,781 bytes in 83 blocks
==22688==         suppressed: 0 bytes in 0 blocks
==22688== Reachable blocks (those to which a pointer was found) are not shown.
==22688== To see them, rerun with: --leak-check=full --show-reachable=yes
==22688== 
==22688== For counts of detected and suppressed errors, rerun with: -v
==22688== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
Abort trap: 6

在这一点上,我不知道去哪里看或做什么。

样本数据:

44  96  3                                                                                                                                                                                                                                                                                                                                                                                       
0   0   17.57298681 24.18012088 0   24.07599728 0   0   0   19.53417371 22.61467731 15.5650829  18.65720893 21.70631048 26.8811321  23.88086356 23.73544942 0   0   22.63088094 21.11777268 22.06847477 22.38688445 19.6794802  20.95594497 22.56472976 15.5058779  0   16.89366861 21.23974633 0   19.01608872 22.58492673 22.39564384 18.17000387 0   0   25.85404904 23.80483437 22.64271243 0   17.09819014 24.60634479 0   24.74696139 29.27117194 20.8931952  19.08648917 23.95167438 0   0   17.2386599  0   0   23.22304254 22.86712074 0   21.45687449 21.45146304 0   0   0   20.98717232 0   18.09871479 17.8226754  23.72508288 23.34563846 21.26201041 17.44038043 22.49848573 18.99848797 16.43222002 14.8132735  22.28093734 17.78931496 0   20.46914933 17.87742323 21.07936723 23.52102135 0   17.90498094 21.93199281 0   0   16.3020812  0   18.17972854 16.43234906 19.0756696  0   0   22.98048214 23.22184013 21.54024161 0

注意,num_pats指的是行数,指a_length的是列数。 b_length是不同输入类型的数量(每行的最后一个数字)。我的示例文件中有 44 行。

4

3 回答 3

4

加载到 t_file 的字符串的大小是多少?你只在那里分配16个字节......

于 2012-09-12T17:08:39.850 回答
0

您没有对“num_pats”进行任何类型的验证。

如果 fscanf 由于某种原因失败,num_pats 可能等于零或负值,这将导致您中止。

于 2012-09-12T16:56:56.550 回答
0

几乎可以肯定,这个问题是由写入未分配的内存引起的。涉及的操作FILE *in看起来不错。

然而,管理动态内存有相当多的复杂性(不管新手——即使对于高级 C 程序员来说,这也是复杂的代码)。由于没有对失败的分配和输入的有效性进行验证检查,因此其中一项分配可能是注销分配的结尾:分配不够大,或者取消引用的方式与原始分配不匹配,使用强制转换时的问题。这样的写入显然会在最终被调用时FILE *in导致fclose()崩溃。这个问题很久以前就出现fclose()了。

如果您包含导致其崩溃的示例输入数据,那么我应该很明显出了什么问题。

于 2012-09-12T17:01:50.720 回答