Вопрос

Итак, у меня есть указатель на массив указателей.Если я удалю его вот так:

delete [] PointerToPointers;

Будет ли это также удалять все указатели на указатели?Если нет, нужно ли мне перебирать все указатели и удалять их, или есть более простой способ сделать это?Мой Google-фу, похоже, не дает мне хороших ответов на этот вопрос.

(И да, я знаю, что мне нужно использовать вектор.Это одно из школьных заданий типа «наверстать упущенное в C++».)

Это было полезно?

Решение

Да, вам нужно перебирать указатели, удаляя их по отдельности.

Причина:Что, если в другом коде есть указатели на объекты вашего массива?Компилятор C++ не знает, правда это или нет, поэтому вам придется говорить явно.

Для «более простого способа» два предложения:(1) Создайте для этой цели подпрограмму, чтобы вам, по крайней мере, не приходилось писать код более одного раза.(2) Используйте парадигму проектирования «умный указатель», где вы храните массив объектов со счетчиками ссылок, а затем объекты удаляются, когда на них больше не ссылается какой-либо код.

Другие советы

Я согласен с Джейсоном Коэном, хотя мы можем немного прояснить причину необходимости удаления указателей с помощью цикла.Для каждого «нового» или динамического выделения памяти необходимо «удалить» освобождение памяти.Иногда «удаление» может быть скрыто, как в случае с интеллектуальными указателями, но оно все равно существует.

int main()
{
  int *pI = new int;
  int *pArr = new int[10];

до сих пор в коде мы выделили два куска динамической памяти.Первый — это просто общий int, второй — массив целых чисел.

  delete pI;
  delete [] pArr;

эти операторы удаления очищают память, выделенную «новыми»

  int ppArr = new int *[10];

  for( int indx = 0; indx < 10; ++indx )
  {
    ppArr[indx] = new int;
  }

Этот фрагмент кода выполняет оба предыдущих распределения.Сначала мы создаем место для нашего int в динамическом массиве.Затем нам нужно пройти цикл и выделить целое число для каждого места в массиве.

  for( int indx = 0; indx < 10; ++indx )
  {
    delete ppArr[indx];
  }
  delete [] ppArr;

Обратите внимание на порядок, в котором я выделил эту память, а затем освободил ее в обратном порядке.Это потому, что если бы мы сделали delete [] ppArr;сначала мы потеряем массив, который сообщает нам, что представляют собой другие указатели.Этот фрагмент или память будут возвращены системе, и поэтому их больше нельзя будет надежно прочитать.

  int a=0;
  int b=1;
  int c=2;

  ppArr = new int *[3];

  ppArr[0] = &a;
  ppArr[1] = &b;
  ppArr[2] = &c;

Думаю, об этом тоже следует упомянуть.Тот факт, что вы работаете с указателями, не означает, что память, на которую указывают эти указатели, была выделена динамически.То есть то, что у вас есть указатель, не означает, что его обязательно нужно удалить.Массив, который я создал здесь, распределяется динамически, но указатели указывают на локальные экземпляры целых чисел. Когда мы удаляем его, нам нужно удалить только сам массив.

  delete [] ppArr;

  return 0;

}

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

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

Указатели — это, по сути, просто ссылки на память, а не маленькие элегантные самоочищающиеся объекты .net.Создание правильных деструкторов для каждого класса сделает удаление более простым, чем массивные циклы по всему коду.

Давайте возьмем (псевдокодированный) пример из реальной жизни. Представьте, что у вас есть такой класс:

class Street
{
    public:
        Street();
        ~Street();
    private:
        int HouseNumbers_[];
}

typedef *Street StreetSign;

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

Массив указателей (концептуально) немного похож на массив целых чисел: это массив чисел, представляющих ячейки памяти различных объектов.Дело не в самих объектах.

Если вы удалите[] массив указателей, все, что вы сделаете, — это удалите массив целых чисел.

Боюсь, тебе придется зацикливаться.

Я не знаю, почему на этот вопрос отвечали так сбивчиво долго.

Если вы удалите массив указателей, вы освободите память, используемую для массива обычно INT.
указатель на объект — это целое число, содержащее адрес.

Вы удалили кучу адресов, но ни одного объекта.

Delete не заботится о содержании пространства памяти, он называет деструктор (ы) и отмечает MEM свободным.

Не все равно, что он просто удалил кучу адресов объектов, просто видит INT.

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

Ну теперь мой ответ получился несколько длинным.......странный...;)

Редактировать:Ответ Джейсона не является неправильным, он просто не попадает в точку.Ни компилятор, ни что -либо еще в C (++) не заботятся о том, что вы удаляете вещи, на которые в другом месте указывают.Вы можете просто сделать это.Другие части программы, пытающиеся использовать удаленные объекты, будут на вас.Но никто вам не помешает.Также не будет проблемой уничтожить массив указателей на объекты, когда объекты ссылаются в другом месте.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top