Как найти ошибку, как отследить ошибку выделения и очищения динамической памяти С++

Помогите понять.

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

Вот текст задачи из источника:

Сформировать динамический двумерный массив (число строк и столбцов запросить у пользователя). Заполнить случайными числами от 1 до 10. Определить номер строки, содержащей максимальный элемент массива. Продублировать эту строку (вставить после данной строки еще одну такую же). Каждое действие с двумерным массивом оформить отдельной функцией, вызываемой из main".

#include<iostream>
#include<cstdlib>

using namespace std;

void init(int **mas, int a, int b){
    for(int i=0;i<a;i++){
        for(int j=0;j<b;j++){
            mas[i][j]=rand()%9+1;
        }
    }
}

void print (int **mas, int a, int b){
    for(int i=0;i<a;i++){
         for(int j=0;j<b;j++){
             cout<<mas[i][j]<<' ';
         }
         cout<<endl;
       }
       cout<<endl;
}

int poisk (int **mas, int a, int b){
     int x=0;
     int max=**mas;//назначение максимальным элементом первый элемент массива(нулевой);
     for(int i=0;i<a;i++){
        for(int j=0;j<b;j++){
            if(mas[i][j]>max){
            max=mas[i][j];//нахождение максимуму массива;
            }
        }
    }
    for(int i=0;i<a;i++){//нахождение номера строки максимального элемента;
        for(int j=0;j<b;j++){
            if(mas[i][j]==max){
            x=i;    
            return x;
             }
          }
       } 
}

void doobl (int **&mas, int &a, int b, int x){/* здесь происходит формирование нового массива, 
     в котором будет продублирована строка с максимальным элементом (первая строка где он попадется); */
     int **mas1=NULL;
     mas1=new int *[a+1];
     for(int i=0;i<a+1;i++){
        mas1[i]=new int [b];
    }
    int j=0;
    for(int i=0;i<=x;i++){
        mas1[j]=mas[i];
        j++;
    }
    for(int i=x+1;i<a+1;i++){
        mas1[j]=mas[i-1];
        j++;
    }
    delete [] mas;//замена старого массива на новый;
    mas=mas1;
    a=a+1;
}

int main(){
    int a, b, c;//а - это строки, b - это столбцы, с - начальное значение генератора случайных чисел;
    cin>>a>>b>>c;
    srand(c);
    int **mas=NULL;
    mas=new int *[a];
    for(int i=0;i<a;i++){
        mas[i]=new int [b];
    }
    init(mas,a, b);//ф-ция заполнения массива;
    print(mas, a, b);//распечатка
    int x=0;
    x=poisk(mas, a,b);//приравнивание переменной к номеру строки с максимальным элементом массива;
    cout<<x;//распечатка номера строки с максимальным элементом массива;
    cout<<endl;
    doobl(mas, a, b, x);//ф-ция дублирования строки с максимальным элементом;
    print(mas, a, b);//распечатка измененного массива;
    for(int i=0;i<a;i++){//отчистка выделенной памяти
        delete [] mas[i];//очищение памяти i-той строки;
    }
    delete [] mas;//очищение памяти массива указателей
}

Мой компилятор DEV C++. При первых запусках программы, происходило аварийное отключение программы и вывод сообщения

процесс завершен с возвращаемым значением 3221226356"(the process is completed with the return value 3221226356).

Но когда я начал комментировать, и попробовал запустить еще раз, все стало нормально: процесс завершен со значением 0.

В чем может быть причина, может ли быть причиной этого глюк в самой среде разработки.

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

Ошибка в". /a.out": двойная ошибка или повреждение (fasttop): 0x0000000000786c60.

То есть все таки где то есть ошибка двойного удаления, как я понимаю. 0x0000000000786c60 Это ведь 16тиричный адрес ячейки памяти? и как я понимаю, я отчищаю его два раза. В общем помогите разобраться. и подскажите как в среде разработки во время отладки вычислять такие ошибки.


Ответы (1 шт):

Автор решения: Anton Shchyrov

Из очевидной лажи, это функция doubl которая приводит к утечкам. И двойное освобождение указателя

void doobl (int **&mas, int &a, int b, int x){/* здесь происходит формирование нового массива, 
     в котором будет продублирована строка с максимальным элементом (первая строка где он попадется); */
    int **mas1=NULL;
    mas1=new int *[a+1];
    // не нужно создавать массивы для значений в строках. Эти массивы уже есть
    /*
    for(int i=0;i<a+1;i++){
        mas1[i]=new int [b];
    }
    */
    for(int i=0;i<=x;i++){
        mas1[j]=mas[i];
    }
    // А вот для новой строки один массив нужно создать
    mas1[x + 1]=new int [b];
    // И скопировать в него значения
    // А иначе мы дважды вызовем delete[] для одного и того же указателя
    for(int i=0;i<b;i++){
        mas1[x + 1][i]=mas[x][i];
    }
    for(int i=x+1;i<a;i++){
        mas1[i + 1]=mas[i];
    }
    delete [] mas;//замена старого массива на новый;
    mas=mas1;
    a=a+1;
}

P.S. Подозревать компилятор и ОС в ошибке стоит в последнюю очередь. В 99.9% случаев все "ошибки компилятора" это ошибки разработчика

→ Ссылка