Как отследить, что вызывает Segfault? - PullRequest
0 голосов
/ 12 октября 2018
typedef struct Cell {
    float   altitude;
    int     type;
}Cell;

void MAZE(FILE *fp, Cell *Map);

int main(void) {

    FILE *fp = fopen("map.bin", "rb");
    Cell *Map;
    Map = read_file(fp);
    char choice;
    while (1) {
        system("color 0f");
        system("cls");
        puts("Main menu:");
        puts("1. Show map by type.");
        puts("2. Show map by altitude.");
        puts("3. Build route.");
        puts("4. Find suitable places for biker jumps.");
        puts("5. Quit.");
        std::cin >> choice;
        std::cin.ignore();
        switch (choice) {
        case '1': {
            display_map_by_type(fp, Map);
            continue;
        }
        case '2': {
            display_map_by_altitude(fp, Map);
            continue;
        }
        case '3': {
            MAZE(fp, Map);
            continue;
        }
        case '5': {
            puts("You've decided to quit.");
            free(Map);
            return 0;
        }
        default: {
            system("color 9f");
            puts("Invalid choice.");
            puts(Press);
            getche();
            continue;
        }
        }
        return 0;
    }
}
void MAZE(FILE *fp, Cell *Map) {
    bool (*initial_maze)[10][10] = (bool (*)[10][10])malloc(sizeof(bool[10][10]));
    if (initial_maze == NULL) {
        fprintf(stderr, NaM);
        exit(-3);
    }
    for (int i = 0; i < 10; i++) {
        for (int j = 0; j < 10; j++) {
            if (Map[i * 10 + j].type == 2 || Map[i * 10 + j].type == 4) {
                *initial_maze[i][j] = false;
            }
            else {
                *initial_maze[i][j] = true;
            }
        }
    }
    for (int i = 0; i < 10; i++) {
        for (int j = 0; j < 10; j++) {
            printf("[%d]", Map[i *10 + j].type);
        }
        putchar('\n');
    }
    putchar('\n');
    for (int i = 0; i < 10; i++){
        for (int j = 0; j < 10; j++) {
            printf("%3s", *initial_maze[i][j] ? "." : "[]");
        }
        putchar('\n');
    }
    getchar();
    free(initial_maze);
}

Эта программа имеет массив объектов, загруженных в кучу - Cell *Map.Массив доступен в main и может быть пройден, а free() - в main или любой другой функции.Тем не менее, по какой-то причине при выборе варианта 3 возникает ошибка. Почему происходит ошибка (и с Cell *Map, и с bool *initial_maze[10][10]), мне неизвестно.По крайней мере, я не нахожу причин для ошибки, нет доступа к неинициализированной памяти, нет нескольких free() -s.Технически есть free() в switch, который находится в цикле, но это все еще не может быть, потому что сразу после этого есть оператор return.В довершение всего, это также не всегда дает сбой, хотя в большинстве случаев происходит сбой.

Отладчики в Visual Studio и Code Blocks указывают на строку free(initial_maze);, но в этом нет ничего плохого, нет ничегоэто могло сделать недействительным массив до этого.

По какой-то странной причине Visual Studio также указала на строку system("color 0f");, как если бы она могла вызвать исключение.

Что касается некоторого контекста, то, что происходит в функции void MAZE(FILE *fp, Cell *Map);.Он должен решить лабиринт, но сначала он должен создать двумерный массив bool, основанный на массиве 1d объектов, переданных ему.

Я прочитал документацию, я знаком с правилами использования динамической памяти.

Если вам нужен вывод:

[0][0][2][3][1][4][1][2][0][3]
[2][1][1][0][3][4][0][2][1][0]
[4][0][4][3][1][1][0][4][1][2]
[2][1][3][1][3][2][1][3][1][0]
[2][2][3][0][0][1][2][4][4][3]
[1][3][2][1][2][2][0][1][1][3]
[4][4][0][3][1][2][0][4][1][2]
[3][0][4][4][4][1][0][3][2][0]
[1][4][3][4][3][4][0][1][1][0]
[1][1][2][2][1][1][3][1][3][3]

  .  . []  .  . []  . []  .  .
 []  .  .  .  . []  . []  .  .
 []  . []  .  .  .  . []  . []
 []  .  .  .  . []  .  .  .  .
 [] []  .  .  .  . [] [] []  .
  .  . []  . [] []  .  .  .  .
 [] []  .  .  . []  . []  . []
  .  . [] [] []  .  .  . []  .
  . []  . []  . []  .  .  .  .
  .  . [] []  .  .  .  .  .  .

, а затем программазависает немного и вылетает.

1 Ответ

0 голосов
/ 12 октября 2018

Отказ от ответственности: Этот ответ для C, так как вы пометили вопрос как таковой.Тем не менее, ваш код на самом деле C ++.


Это простая ошибка приоритета оператора, *initial_maze[i][j] должно быть (*initial_maze)[i][j].Поскольку [] имеет более высокий приоритет, чем *, вы в конечном итоге ссылаетесь на массив bool[10][10] times i, который не был намерением.

Но вместо этого измените вызов malloc на следующее:

bool (*initial_maze)[10] = malloc(sizeof(bool[10][10]));

А затем получите к нему доступ initial_maze[i][j].Гораздо легче читать.

Хотя, как уже упоминалось в комментариях, динамическая память, в первую очередь, практически не требуется.Вы можете просто создать локальный 2D-массив.

...