Свободный динамический массив статических массивов? - PullRequest
0 голосов
/ 26 октября 2018

У меня есть код, подобный этому

РЕДАКТИРОВАТЬ этот код должен быть на интерфейсе, поэтому разрешен только POD.Нет векторов, нет контейнеров.

int (*neco)[2];

int ahoj = 2;
neco = new int[ahoj+2][2];
int iter = 1;
for (size_t i = 0; i < 4; i++)
{
    for (size_t j = 0; j < 2; j++)
    {
        neco[i][j] =iter;
        iter++;
    }

}

for (size_t i = 0; i < ahoj + 2; i++)
{
    delete[] neco[i];
}

Это не работает.Удаление удаляет память, не выделенную.Даже

delete [] neco;

или любое другое удаление.Каждый из них удаляет память ДО выделенного блока.

Поиск в Google и консультации с коллегами в офисе не дали результатов.:)

Как мне выделить динамический массив «точек» (две координаты) и затем освободить их?

Я могу решить эту проблему, используя другую структуру.

Но иногда я могу выделить память.Запишите в выделенную память…

Как правильно освободить эту память?(Просто академический вопрос.)

Ответы [ 3 ]

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

Если я правильно помню, массив массивов (будь то динамический или статический) - это, в основном, матрица.

Итак, академический ответ:

Точно так же, как вы выделяете память (сначала выделяете память массива массивов, затем с помощью for вы выделяете память массивов внутри массива), чтобы освободить ее, вам нужно удалить в for память массивов, а затем, в простом delete, освободить память динамического массива.

Итак:

arrayOfArrays[[array1][array2][array3][array4]]

означает: выделить память arrayOfArrays, затем в цикле выделить память array(number)

То же самое происходит и наоборот.

Свободная память arrayOfArrays в одном предложении.

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

Общее правило состоит в том, что каждому выражению new должно соответствовать одно соответствующее выражение delete.

Ваше выражение new является правой частью оператора

neco = new int[ahoj+2][2];

поэтому соответствующее выражение delete дано в выражении

delete [] neco;

Если это не сработает (как вы и утверждаете), это означает, что проблема в каком-то другом коде, демонстрирующем неопределенное поведение.

Ваш цикл

for (size_t i = 0; i < ahoj + 2; i++)
{
    delete[] neco[i];
}

неверен, поскольку ни один из neco[i] не является результатом выражения new.Так что delete [] neco[i] имеет неопределенное поведение в каждой итерации цикла.

Учитывая, что ваш пример кода (ов) и описание неполны, я сомневаюсь, что кто-то еще может дать более полезный совет.

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

#include <vector>

int main()
{
     std::vector<int[2]> avec(ahoj + 2);     
     int (*neco)[2] = &avec[0];

     for (size_t i = 0; i < ahoj + 2; ++i)
     {
         for (size_t j = 0; j < 2; ++j)
         {
             neco[i][j] = iter;
             ++iter;
         }
     }
}

Единственная разница в том, что avec выполняет динамическое выделение и освобождение памяти для вас.neco по-прежнему является указателем на массив, требуемый (согласно вашему описанию) вашим API.Два подхода к этому подходу таковы:

  • не изменяет размер avec после инициализации neco (или не инициализирует neco при изменении размера avec)
  • donНе используйте neco после того, как avec прекратит свое существование (поскольку поведение будет неопределенным).

Кроме того, ни один из массивов на самом деле не является статическим.Так что ваш вопрос ошибочен.

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

Простые указатели на динамически распределенную память доставляют вам неприятности.

Используйте std::unique_ptr:

#include <memory>
// ...
std::unique_ptr<int[][2]> neco(new int[ahoj+2][2]);

И удалите этот цикл с помощью delete[].

В качестве альтернативы, используйте std::vector<int[2]> neco(ahoj+2) - он управляет памятью и может быть изменен.

...