1

十分にコンパイルできるコードがありますが、それを実行しようとすると、セグメンテーション違反が発生し、何が問題なのかわかりません。

プログラムのポイントは、さまざまなサイズとフラグメント数の fragmentet ASCII アート ファイルのテキストをつなぎ合わせることです。フラグメントの名前は 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() に何か問題があることがわかりました。これは、fileName 配列が原因だと思われますが、いくつか変更したところ、デバッガーから得られるのは次のとおりです。

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 はどちらもありません...そして、古き良き 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 ()
4

4 に答える 4

3

おそらく、それが存在しないことを示してfileいると思います。NULL*fileName

次のようなステートメントに注意してください。

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

おそらく期待したことをしないでください。そのステートメントは、次と同等です。

fileName[5] = xTens;

intにを割り当てているので、コンパイラの警告が表示されるはずですchar*

代わりに、おそらく-スタイルのフォーマットをsnprintf使用してファイル名を作成することを意図していました。printf

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

2回目のクラッシュの場合:に必要のないポインターの追加レイヤーがありますarray。として宣言し、アクセスするときにchar array...削除します。*現在のところ、要素はポインタになることをコンパイラに伝えましたが、どこにもポイントさせていないので、を使用してポイントしている場所を確認するようコンパイラに依頼しました*。ブーム!

thenを最後に使用するにはarray、に渡す各文字へのポインタを作成する必要がありますfwrite&これは、のように使用される「address-of」と呼ばれる演算子を使用して行い&array...ます。

address-of演算子は。の反対です*。プログラムが機能するようになったら、&他の場所を使用してコードを簡略化できます。たとえば、int *widthを使用してヒープから宣言して割り当てる代わりに、すべてmallocの場所を削除し*てに渡す&widthことができますscanf


セグメンテーション違反に戻ったので、使用する前にfreadの戻り値を確認してください。fopenの場合NULLは、エラーメッセージを出力します。

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

それはおそらく何が悪いのかを教えてくれるでしょう。ただし、これはデバッグコードではありません。通常、呼び出す関数からのエラーリターンを確認する必要があります。

于 2012-11-12T02:02:56.547 に答える
2

*width を使用する前に何にも設定していません。

サイズを読んだ後、割り当てを行いたいと考えています。

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;

私はあなたがpythonについて考えていると思います。

于 2012-11-12T02:00:20.707 に答える
1

デバッガーの使い方を学ぶための+1:)「fopen」の戻り値をチェックしていません。fileに渡される値は何freadですか?

于 2012-11-12T02:04:08.967 に答える
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()が正しくないようです。

于 2012-11-12T02:02:19.727 に答える