2016-09-06 93 views
0

我有一個代碼,應該爲監管目的生成一個曲線,工作正常。簡單的calloc和FILE代碼在窗口上隨機崩潰

來自Linux環境,我真的不知道如何在Windows上編碼(我不得不在工作中使用),所以我繼續下載Code :: Blocks和MinGW

現在的問題如下:我的代碼工作,但有時它崩潰。我在Linux上嘗試過,我沒有任何問題,但是在Windows上,它有時會起作用,有時它不會告訴我這一點。

Problem signature: 
    Problem Event Name: APPCRASH 
    Application Name: TabGen.exe 
    Application Version: 0.0.0.0 
    Application Timestamp: 02881c68 
    Fault Module Name: ntdll.dll 
    Fault Module Version: 6.1.7601.23418 
    Fault Module Timestamp: 5708a73e 
    Exception Code: c0000005 
    Exception Offset: 00032a62 
    OS Version: 6.1.7601.2.1.0.256.48 
    Locale ID: 2055 
    Additional Information 1: 0a9e 
    Additional Information 2: 0a9e372d3b4ad19135b953a78882e789 
    Additional Information 3: 0a9e 
    Additional Information 4: 0a9e372d3b4ad19135b953a78882e789 

說實話,我不太明白。我試圖查找「異常代碼c0000005窗口」,這顯然意味着「訪問違規」,但我不明白它來自哪裏,因爲如所述,有時它有時不工作。

與MinGW有關嗎?我在代碼中做錯了什麼?我有一個函數mk_cp_table(它始終使用4096個值,這就是爲什麼它不是一個函數參數),但我很積極,這是沒問題的。

此外,如果你想知道爲什麼我使用calloc而不是數組,這又是因爲我不明白的錯誤。最後一個函數末尾的fprintf不起作用,如果我在數組中有我的值(但是單獨使用printf顯示它們完美工作,但fprintf只會在我運行它時留下空白文件)。

任何想法?

我的代碼:

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

void tab2file(FILE*, int, int*); 
void mk_cp_table (int*, float, float, float, int, float, float, int); 

int main (void) 
{ 
    FILE* cp_file = fopen("cp_table.txt", "w"); 

    if (cp_file == NULL) 
    { 
     perror("failed fopen for cp_file\n"); 
     exit(EXIT_FAILURE); 
    } 

    int* cp_table = calloc((size_t) 4096, sizeof (int)); 

    if (cp_table == NULL) 
    { 
     fclose(cp_file); 

     perror("failed calloc for cp_table\n"); 
     exit(EXIT_FAILURE); 
    } 

    /* Generate curves */ 

    mk_cp_table(
     cp_table, 
     0.142,  /* scale */ 
     20,   /* zeroed distance 0 (negative part) */ 
     0.04,  /* slope 0 */ 
     120,  /* range 0 */ 
     20,   /* zeroed distance 1 (positive part) */ 
     0.04,  /* slope 1 */ 
     120   /* range 1 */ 
    ); 

    printf("\ntable generated\n"); 

    tab2file(cp_file, 4096, cp_table); 

    printf("\ntables written to files\n"); 

    fclose(cp_file); 
    free(cp_table); 

    return EXIT_SUCCESS; 
} 

void tab2file(FILE* file, int size, int* table) 
{ 
    int i; 

    for (i = 0; i < size; i++) 
     fprintf(file, "%d\n", table[i]); 
} 

void mk_cp_table(int* table, float scale, float zeroes_0, float slope_0, int range_0, float zeroes_1, float slope_1, int range_1) 
{ 
    int i; 
    int value; 

    zeroes_0 = zeroes_0/scale; 
    zeroes_1 = zeroes_1/scale; 

    for (i = 0; i < 2048; i++) 
    { 
     if (i < zeroes_1) 
      value = 0; 

     else 
      value = (i - zeroes_1) * slope_1; 

     if (value > range_1) 
      value = 127; 

     table[i] = 0; 
    } 

    for (i = 0; i < 2048; i++) 
    { 
     if (i < zeroes_0) 
      value = 0; 
     else 
      value = (zeroes_0 - i) * slope_0; 

     if (value < -range_0) 
      value = -127; 

     table[4096 - i] = value; 
    } 
} 
+3

'table [4096 -i] = value'當'i' == 0時,它寫入'table'的範圍之外。 – Michael

+0

@邁克爾:那是心靈感應,我正要評論完全相同的東西! –

+0

@Luda Otaku您正在寫出界限,並在您的程序的最後一行遇到類似於seg錯誤的窗口。 – gowrath

回答

1

爲了完整,所以這個問題不會保留在沒有答案的部分,你在你的程序中的最後一行在編寫出界的for循環:

for (i = 0; i < 2048; i++) 
{ 
    if (i < zeroes_0) 
     value = 0; 
    else 
     value = (zeroes_0 - i) * slope_0; 

    if (value < -range_0) 
     value = -127; 

    table[4096 - i] = value; // out of bounds when i = 0. 
} 

這會導致窗口等效於seg故障,即訪問衝突。如果你在valgrind下運行它,你也會注意到這個問題。

+0

Syncro!我同時發佈了自己的答案。謝謝 ! – saeleko

0

事實證明這是一個分段錯誤,我有table[4096 - i] = value;這將是出數組邊界的時候,我是等於0

有時當你過於注重你以爲代碼的一部分沒有工作,你忘了檢查你認爲工作的部分。

2

對於4096個元素的數組,4095是您可以使用的最大有效索引。當i == 0時,語句table[4096 - i] = value;寫入table[4096],該值超出table的範圍。

大概你打算做table[4095 - i] = value;,它會給你一個4095..2048的索引。