2012-09-12 46 views
3

我無法正確運行一些C代碼(請耐心等待,如果這個問題很愚蠢,因爲我是C新手;另外,所以每個人都清楚,這是我在運行時遇到的代碼。我寫的部分是空文件句柄檢查)。基本上,我的程序崩潰在fclose。代碼第一:SIGABRT in 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問題,我遇到this SO post,害得我用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行。

+0

沒有'label'的聲明。你是否正確複製/粘貼? – wallyk

+0

這可能是由於其他地方的溢出。 – md5

+0

@wallyk - 不,不正確。修正了這一點,謝謝。 – learner

回答

4

加載到t_file中的字符串的大小是多少?你只在那裏分配16個字節...

+0

該字符串是'/ Users/aaaaaaaaaaaa/Desktop/bcell062012NN.csv'(個人名稱編輯,字符串長度保留)。 – learner

+0

在這種情況下,gets()正在搞砸你。 (或者scanf(),結果相同) – wildplasser

+0

謝謝wildplasser - 那正是問題所在。我增加了't_file'(到126;可能默認爲500)並且程序成功執行。我在工作時正在閱讀K&R,但還有很多需要解決的問題...... – learner

0

你沒有對「num_pats」進行任何類型的驗證。

如果由於某種原因fscanf失敗,num_pats可能會等於零或爲負值,這會導致您墮胎。

+0

這是真的。但在我的測試數據中,'num_pats'是正確的。 – learner

+0

嘗試使用valgrind --tool = memcheck。它會告訴你,如果你寫出的界限可能是這裏發生的事情。 – caruizdiaz

+0

'--tool = memcheck'給出與我的文章相同的結果。 – learner

0

幾乎可以肯定的是,問題是由於寫入未分配的內存引起的。涉及FILE *in的操作看起來很好。但是,你在管理動態內存方面有相當的複雜性(不用擔心菜鳥—這是複雜的代碼,即使是高級C程序員也是如此)。由於沒有對失敗的分配和輸入的有效性進行驗證檢查,所以這些分配中的一個可能會註銷分配的結尾:分配不夠大或者解除引用的方式與原始分配不匹配,使用強制轉換時出現問題。這樣的寫明顯在貶低FILE *in中的某些內容,導致fclose()在最終調用時崩潰。雖然在fclose()之前很久就出現了這個問題。

如果你包含導致它崩潰的示例輸入數據,它應該對我來說很明顯是什麼問題。

+0

我已添加示例數據。謝謝回覆。 – learner