Перестановка указателей в двумерном динамическом массиве

Рейтинг: 1Ответов: 1Опубликовано: 09.12.2014

Есть динамический массив

int **create_array(size_t m, size_t n) {
    int **arr = new int *[m];
    arr[0] = new int[m * n];
    for (size_t i = 1; i != m; ++i)
        arr[i] = arr[i - 1] + n;
    return arr;
}

Необходимо поменять местами с нулевой строку,содержащую минимальный элемент, т.е. поменять указатели

В функции обмена происходит выход за границы массива. Не могу понять почему.

void swap_min(int **mt, int m, int n) {
    int number_row = 0;
    int min = *(*mt);
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) {
            if (*(*mt + i * n + j) < min) {
                min = *(*mt + i * n + j);
                number_row = i;
            }
        }
    }
    if (number_row == 0)
        return;
    else {
        int *tmp = mt[number_row];
        mt[number_row] = mt[0]; // после этой строчки не происходит ничего
        mt[0] = tmp;  // вот после этой строчки ошибка
    }
}

Что я делаю неправильно?

Ответы

▲ 1

Эээ, подождите. *(*mt + i * n + j) < min? Вы имели в виду mt[i][j]? Тогда так и пишите.

Тем более, если у вас данные идут подряд только в самом начале, а потом вы двигаете указатели, то этот код и вовсе неверен.

Обращение к mt[0] не может быть причиной ошибки, т. к. mt[0] — это то же, что *mt, а к этому элементу вы уже обращались. Попробуйте просмотреть адреса под отладчиком. Ошибка где-то ещё.

Обновление

Я оттрассировал ваш код. Ошибки, ведущей к вылету, в самой указанной вами строке нету. Но обращение к *mt + i*n + j после перестановки неверно (а оно у вас происходит в двух местах: в show(ar, M, N) и в free_array(ar, M)), и является undefined behaviour. Программы с undefined behaviour имеют право вести себя как угодно и вылетать в любом месте, особенно если у вас хороший оптимизирующий компилятор. Могу поспорить, если вы закомментируете вызовы show и free_array, вылета не будет.