2012-11-12 36 views
1

我已經有了編譯好的代碼,但是當我嘗試運行它時,出現了分段錯誤,我無法弄清楚什麼是錯誤的。我的分段錯誤在哪裏?

該計劃的重點是將不同尺寸和片段數量的碎片文件文件拼湊在一起。 片段被命名爲part_xx-YY,其中xx是從00到11和YY是從00到05

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


int main(void) 
{ 
    int width; 
    int height; 
    int xPieces; 
    int yPieces; 
    int xTens=0; 
    int xOnes=0; 
    int yTens=0; 
    int yOnes=0; 
    printf("Fragment width: "); 
    scanf("%d", &width); 
    printf("Fragment height: "); 
    scanf("%d", &height); 
    printf("Number of fragments on x axis: "); 
    scanf("%d", &xPieces); 
    printf("Number of fragments on y axis: "); 
    scanf("%d", &yPieces); 
    printf("wtf0"); 
    char *line=malloc(sizeof(width) * sizeof(char)); 
    printf("wtf1"); 
    char array[xPieces][yPieces][height][width]; 
    printf("wtf2"); 
    char fileName[50]; 
    printf("wtf3"); 
    for(int x = 0; x<xPieces;) 
    { 
     printf("%d", x); 
     for(int y = 0; y<yPieces;) 
     { 
      printf("%d", y); 
      if(xOnes>=10) 
      { 
       xOnes=0; 
       xTens++; 
      } 
      if(yOnes>=10) 
      { 
       yOnes=0; 
       yTens++; 
      } 
      snprintf(fileName, sizeof fileName, "part_%i%i-%i%i", xTens, xOnes, yTens, yOnes); 
      FILE *file=fopen(fileName, "r"); 
      char buffer[(width) * (height)]; 
      fread(buffer, 1, (width) * (height), file); 
      for(int i = 0; i<height; i++) 
      { 
       printf("%d", i); 
       for(int j = 0; j<width; j++) 
       { 
        printf("%d", j); 
        array[x][y][i][j] = buffer[j + (i * (width))]; 
       } 
      } 
      fclose(file); 
      y++; 
      yOnes++; 
     } 
     x++; 
     xOnes++; 
    } 

    FILE *newFile=fopen("newFile", "w"); 

    for(int y = 0; y<yPieces; y++) 
    { 
     for(int i = 0; i<height; i++) 
     { 
      for(int x = 0; x<xPieces; x++) 
      { 
       for(int j = 0; j<width; j++) 
       { 
        fwrite(&array[x][y][i][j], 1, 1, newFile); 
       } 
      } 
     } 
    } 

    fclose(newFile); 
    free(line); 
} 

我想出如何使用調試器,並表示有什麼錯用fread() ,我想這是我的文件名陣列造成的,但我改變了一些東西,現在我在調試器得到的是這樣的:

Program received signal SIGSEGV, Segmentation fault. 
0x0018d68c in fread() from /lib/tls/i686/cmov/libc.so.6 

我想也許FREAD()試圖讀入一個太小緩衝區,所以我增加了緩衝區到10000(這應該是戲劇性的過度殺傷力),但唉,無濟於事。 我已經研究了很多,在這個問題上奮鬥了幾個小時,但仍然不知道如何從這裏走得更遠,因爲我發現的類似問題對我來說沒有多大意義,或者不相似足夠。

我認爲在這一點上我需要別人來看我的代碼,所以任何幫助將不勝感激。

更新:我已經更新了我的代碼有一些變化,現在我在這裏得到一個分段錯誤,而不是:

Program received signal SIGSEGV, Segmentation fault. 
0x08049058 in main() at innlev3.c:50 
50      *array[x][y][i][j] = buffer[j + (i * (*width))]; 

我認爲這部分是相當不錯......我做了什麼錯了,在這裏?

更新2:代碼再次更新。我發現了一些我認爲很奇怪的東西......在我的scanf工作之後,這些printf都沒有... Aand我回到了舊的fread()細分故障。我想這是一件好事,我沒有提出一個新的問題...:P

Program received signal SIGSEGV, Segmentation fault. 
0x0018d68c in fread() from /lib/tls/i686/cmov/libc.so.6 
(gdb) backtrace 
#0 0x0018d68c in fread() from /lib/tls/i686/cmov/libc.so.6 
#1 0x08048fc6 in main() 
+0

你應該問你的調試器這種類型的問題。 – 2012-11-12 02:13:03

+0

我已經更新了一個新的分段錯誤。這是好的還是我應該提出一個新的問題? – Dzyu

+0

我想說這足以讓我成爲一個單獨的問題,但我懷疑Stack Overflow警察會來敲門。 ;-)我在下面回答你的新問題。 –

回答

3

我猜fileNULL,可能表明*fileName不存在。

注意,聲明是這樣的:

fileName[5] = "%i",xTens; 

不這樣做,你可能期望。該聲明等同於:

fileName[5] = xTens; 

這應該給你一個編譯器警告,因爲你分配一個intchar*

相反,您可能打算使用snprintf來使用printf風格的格式來構造文件名。

char filename[50]; 
snprintf(filename, sizeof filename, "part_%i%i-%i%", xTens, xOnes, yTens, yOnes); 
FILE *file=fopen(fileName, "r"); 

關於你的第二崩潰:你有你不需要在array指針額外的一層。將其聲明爲char array...,並在訪問它時刪除*。就目前而言,你已經告訴編譯器,這些元素將是指針,但是你沒有將它們指向任何地方,然後你讓編譯器使用*去查找它們指向的位置。繁榮!

您最後的使用array然後需要指向每個字符傳遞到fwrite。您可以使用&運營商的名稱,稱爲「address-of」,用於&array...

地址運算符與*相反。一旦你的程序工作,你可以使用&其他地方來簡化你的代碼。例如,您可以不使用聲明int *width並使用malloc從堆中分配它,而是可以將*隨處移除,並將&width更改爲scanf


由於我們回到fread段錯誤:在使用前檢查的fopen返回值。如果它是NULL,則顯示錯誤消息。

if(file == NULL) 
{ 
    printf("can't open %s\n", fileName); 
    exit(1); 
} 

這可能會告訴你什麼是錯的。但是,這不是調試代碼。你通常應該檢查你所調用函數的錯誤返回。

+0

啊,我明白了。這使我通過fread()segfault,但現在我又得到了另一個: 編程接收到的信號SIGSEGV,分段錯誤。在innlev3.c 0x08049058在main():50 50 \t \t \t \t \t \t *陣列[X] [Y] [i] [j] =緩衝液[J +(I *(*寬度))]; – Dzyu

+0

啊,我已經開始討論這個問題了。很高興知道我對這些指針有了更好的掌握。 :) 我現在又回到舊fread()分段錯誤,我發現一個好奇心:沒有任何printf(「我添加的wtf,打印...代碼更新和您的幫助非常感謝。:) – Dzyu

+0

你的'printf'調用正在工作,但是因爲你沒有在它們的末尾添加換行符「\ n」,所以它們的輸出會被緩衝,直到你打印換行符 –

2

您在使用它之前沒有設置寬度。

您想在閱讀尺寸後進行分配。

printf("fragment width: "); 
scanf("%i", width); 
printf("fragment height: "); 
scanf("%i", height); 
char *line=malloc(sizeof(*width) * sizeof(char)); 

而且,這不是做什麼,你認爲它是:

 FILE *file=fopen(*fileName, "r"); 

這是要打開一個名爲「P」檔。

這是什麼你覺得它沒有做任何:

 fileName[5] = "%i",xTens; 

我想您所想的蟒蛇。

+0

這似乎不是真的 - 有一個'scanf'應該設置'* width'。 –

+0

@JameySharp:但是scanf是在* width被使用後完成的。 –

+0

啊,我明白了你的觀點 - 但是隨後使用未初始化的'width'分配的變量'line'不會在任何地方使用,並且不會在那裏發生崩潰,而是在稍後發生。 –

1

如果運行gdb和回溯你看到這一點:

Program received signal SIGSEGV, Segmentation fault. 
0x00007ffff7a8a724 in fread() from /lib/x86_64-linux-gnu/libc.so.6 
(gdb) backtrace 
#0 0x00007ffff7a8a724 in fread() from /lib/x86_64-linux-gnu/libc.so.6 
#1 0x0000000000400ad1 in main() 

這意味着你在fread崩潰。 fread()中的文件變量似乎不正確。

+0

感謝您的回溯提示。我將在未來使用它。 :) 現在,更新我的代碼後出現的新分段錯誤只給了我同樣的事情,如果我做一個簡單的回溯,並且我在這裏也看不到我的代碼有什麼問題。 – Dzyu

1

+1學習使用調試器:)你沒有檢查「fopen」的返回值。什麼值file正在傳遞給fread