Ahmed AE Ответов: 3

Почему это не достаточно, чтобы использовать Delete [], чтобы удалить 2Д динамически выделенный массив?


Я использовал следующий код для создания 2D динамически выделенного массива:
int x,y;
    cout<<"Entre matrix dimensions"<<endl;
    cin>>x>>y;

    //Dynamically Allocating x*y array
    int **myArray = new int*[x];              //reserve x row elements
    for (int i = 0; i < x; ++i) {
        for (int j = 0; j < y; ++j) {
            myArray[i] = new int[j];           //makes each one of the reserved row elements points to an array
        }
    }

    //entreing the values
    cout<<"Entre the values"<<endl;
    for (int i = 0; i < x; ++i) {
        for (int j = 0; j < y; ++j) {
            cin>>myArray[i][j] ;
        }
    }

    //Displaying the values
    cout<<"You entred : "<<endl;
    for (int i = 0; i < x; ++i) {
        for (int j = 0; j < y; ++j) {
            cout<<myArray[i][j]<<" " ;
        }
        cout<<endl;
    }

Когда я тестировал предыдущий код, он работал хорошо.Но когда я попробовал следующий код, чтобы освободить 2d-массив:
 //Memory Deallocation
 for (int i = 0; i < x; ++i) {
         delete [] myArray[i];
     }
delete[] myArray;

Произошла ошибка:
Heap corruption detected. CRT detected that the application wrote to memory after end of heap buffer


Что я уже пробовал:

Я пытался просто использовать
delete[] myArray;
для освобождения памяти и сообщения об ошибке не появилось. Но я не знаю, правильно это или нет?

3 Ответов

Рейтинг:
21

Jochen Arndt

Это потому, что ваш delete код не соответствует коду распределения:

//Dynamically Allocating x*y array
int **myArray = new int*[x];              //reserve x row elements
for (int i = 0; i < x; ++i) {
    for (int j = 0; j < y; ++j) {
        myArray[i] = new int[j];           //makes each one of the reserved row elements points to an array
    }
}
//Memory Deallocation
for (int i = 0; i < x; ++i) {
    delete [] myArray[i];
}
delete[] myArray;
Для каждого x вы распределяете y массивы, которые все назначены myArray[i] Таким образом, будет использоваться (а затем освобождаться) только последний выделенный. Кроме того, этот последний имеет размер y-1 это является причиной повреждения кучи, потому что вы получаете доступ к еще одному (не выделенному) элементу.

Просто используйте один цикл для выделения, например, при удалении:
for (int i = 0; i < x; ++i) {
    myArray[i] = new int[y];
}


Ahmed AE

А как насчет использования только delete[] для его удаления?

Jochen Arndt

Это приведет только к удалению myArray, а не тех элементов, которые тоже были выделены. Это привело бы к "утечке памяти" (выделив память, которая больше не используется).

Ahmed AE

Как это проверить?

Jochen Arndt

Просто найдите "детекторы утечки памяти c++". Они должны быть добавлены в ваш код и выполняться при завершении работы приложения.

Рейтинг:
2

KarstenK

Вы выделили правильную память для вашего массива, поэтому вы получаете этот беспорядок. Ты ошибка КОГДА доступ к недопустимой памяти и НЕ при удалении (правильно выделенного, но неправильно используемого) блока памяти.

этот код должен делать свою работу:

int *myArray = new int[x * y];//allocate array of size (fixed the wrong "+" operator to "*"
delete[] myArray;//cleanup 

Совет: используйте окно просмотра памяти, чтобы увидеть данные и немного поиграть с ними. ;-)


Richard MacCutchan

Должно быть new int[x * y]; // x строк каждый из y столбцов

CPallini

Хороший улов!

Ahmed AE

Он привел меня в замешательство.

KarstenK

s bug => Я исправлю это

Usman Hunjra

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

Рейтинг:
18

CPallini

Ваш delete все в порядке. Ваше распределение памяти неверно.
Попробуй:

#include <iostream>
#include <cstdlib>
using namespace std;

int main()
{
  int x,y;
  cout<<"Entre matrix dimensions"<<endl;
  cin>>x>>y;
  cout << "x = " << x << ", y = " << y << endl;


  //Dynamically Allocating x*y array
  int **myArray = new int * [x];              //reserve x row elements
  for (int i = 0; i < x; ++i)
    myArray[i] = new int[y];

  cout << "assigning random values"<< endl;
  for (int i = 0; i < x; ++i)
    for (int j = 0; j < y; ++j)
      myArray[i][j] = rand();

  //Displaying the values
  cout<<"the values : "<<endl;
  for (int i = 0; i < x; ++i)
  {
    for (int j = 0; j < y; ++j)
      cout<<myArray[i][j]<<" " ;
    cout << endl;
  }

  //Memory Deallocation
  for (int i = 0; i < x; ++i)
    delete [] myArray[i];

  delete[] myArray;
}


Кстати, стандартная библиотека мягко предоставляет вам vector контейнер, почему ты им не пользуешься?


Ahmed AE

потому что я буду использовать эти матрицы в математических расчетах. И вектор будет потреблять больше ресурсов процессора и оперативной памяти.

CPallini

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

Ahmed AE

Хорошо, я попробую

Ahmed AE

Но как насчет использования только delete[] myArray;
как освобождение массива?

CPallini

Нет, вы не должны. Опять же, освобождение в вашем фрагменте кода является правильным.