1

作成しているこのCプログラムで実行時にSTATUS_ACCESS_VIOLATIONを取得しています。これは、構造体を一度に初期化し、malloc()を使用してサイズを大きくし、ポインターが既に使用されているメモリを参照するためだと思います。これは、この例外が発生する関数です。

void process_track(char filename[], struct track *tracks) {
    int i = 0;
    FILE* fp;
    int lines;
    lines = count_file_lines(filename);
    tracks = malloc(lines);
    fp = fopen(filename, "r");
    if (fp == NULL) {
        printf("\n\"%s\" File not found", filename);
        exit(1);
    } else {
        for (i = 0; i < lines; i++) {
            fscanf(fp, "%d %d %d %d\n", &tracks[i].number, &tracks[i].startnode, &tracks[i].endnode, &tracks[i].minutes);
        }
        for (i = 0; i < lines; i++) {
            printf("%d ", tracks[i].number);
            printf("%d ", tracks[i].startnode);
            printf("%d ", tracks[i].endnode);
            printf("%d\n", tracks[i].minutes);
        }
    }
}

具体的には、次の行で発生します。

fscanf(fp, "%d %d %d %d\n", &tracks[i].number, &tracks[i].startnode, &tracks[i].endnode, &tracks[i].minutes);

この関数は、次の関数で呼び出されます(ケース3)。

void get_file(char textfilename[], int optnumber) {
    struct node *nodes;
    struct track *tracks;
    struct course *courses;
    struct entrant *entrants;
    struct checkpointdata *checkpointdatas;
    char filename[20]; //Array of char for filename
    printf("Enter the name of the %s text file(with file extension) :", textfilename);
    scanf(" %[a-zA-Z._1-9]", &filename);
    switch (optnumber) {
        case 1:
            process_name(filename);
            break;
        case 2:
            process_node(filename, nodes);
            break;
        case 3:
            process_track(filename, tracks);
            break;
        case 4:
            process_course(filename, courses);
            break;
        case 5:
            process_entrant(filename, entrants);
            break;
        case 6:
            process_checkpointdata(filename, checkpointdatas);
            break;
    }

}

最初の行は正常に読み取られますが、その後は失敗します。他の「process_[data]」もよく似ているので、それらも試してみました。正常に動作するものもあれば、例外が発生するものもあり、出力時にガベージを取得するものもあります。

これを回避するにはどうすればよいですか、または事前に割り当てられたメモリと衝突しないようにメモリを割り当てます(これが実際に問題である場合)?

4

1 に答える 1

2

malloc()要素の数ではなく、割り当てるバイト数を受け入れます。lines投稿されたコードはバイトを割り当てるだけです:

tracks = malloc(lines);

これはの配列には不十分であり、割り当てられたメモリブロックの境界を超えて書き込みおよび読み取りをstruct track行う後続のループが発生します。for要素のサイズと要素の数を渡します。

tracks = malloc(lines * sizeof(*tracks));

関数内で行われた変更はtracks、その関数にのみ表示されることに注意してください。関数の呼び出し後に実際には使用されないためtracks、引数をローカル変数に置き換えることができます。

malloc()すべてにが必要であることを忘れないでくださいfree()

于 2012-12-14T09:08:15.567 に答える