WedX - журнал о программировании и компьютерных науках

Удалить связанный список перед закрытием программы на С++?

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

Связанный список имеет дело с указателями и динамическим размещением. Таким образом, они предоставили ключевое слово new, которое выделяет кусок (я полагаю, так он пишется) памяти в хранилище heap и возвращает указатель, указывающий на него. И они также предоставили ключевое слово delete, которое освобождает память, на которую указывает указатель, возвращаемый новым.

Итак, предположим, я создал связанный список, скажем, из 10 узлов, тогда должен ли я создать функцию для сканирования каждого узла и удаления каждого узла? Потому что в моем учебнике написано, что если вы не удалите динамически размещенный объект, это приведет к утечке памяти...

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


Дополнительные детали

Операционная система Windows 7

Компилятор Turbo C++

c++
20.01.2014

  • До закрытия программы? Строго говоря, нет. Но это хорошая практика. 20.01.2014
  • @MitchWheat Не путай бедного парня. 20.01.2014
  • @ Джон Диблинг: Нет. Это 100% правильно. 20.01.2014
  • Так ты думаешь, что я бедный парень, да?? 20.01.2014
  • @TheDreamCoder17: Я пошутил. 20.01.2014

Ответы:


1

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

Тем не менее, вся память, используемая программой, будет освобождена операционной системой при закрытии программы. Но я думаю, что ваш учитель (домашнее задание, не так ли?) или начальник предпочли бы, чтобы вы освободили память.

Суть такова: delete все, что вы создали с помощью new.

20.01.2014

2

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

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

Однажды, если вы знаете, ваша heap память больше не нужна, лучше ее delete (вместо ожидания закрытия программы)

{
  Allocation with new...
  call function(using allocated memory)
  ....
  ....
  call function2(using allocated memory)

  not using allocated memory here after..
  **Delete Your heap memory..**

  call AnotherFunction()
  ....
  ...

  Alternatively, you can release / delete memory here also. (Good practice than not deleting :) )
  end of main / application.
}
20.01.2014

3

Нет, на самом деле вам необходимо это делать.

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

Другими словами, вы должны не обычно иметь что-то вроде:

// WARNING: bad code. Avoid this, or anything similar.
struct node {
    int data;
    struct node *next;
};

node *head = NULL;

int main() { 
     node *t = new node;
     t->data = 1;
     t->next = head;
     head = t;

     t = new node;
     t->data = 2;
     t->next = head;
     head = t;

     // here, do we bother to delete the two nodes or not?
};

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

class linked_list {
    struct node { 
        int data;
        node *next;

        node(int data, node *next = NULL) : data(data), next(next) {}    
    } *root;
public:
    void add(int data) {
        root = new node(data, root);
    }

    ~linked_list() { 
       node *prev = root;
       for (node *temp = prev->next; temp!=NULL; temp=temp->next) {
            delete prev;
            prev = temp;
       }
       delete prev;
    }       
};

С таким классом действительно нет решения:

int main() { 
    linked_list x;

    x.add(1);
    x.add(2);
}

Когда выполнение достигает конца блока, в котором было определено x, x выходит за рамки и уничтожается. В процессе вызывается его деструктор, который удаляет узлы в связанном списке (конечно, по модулю любых ошибок в моем коде). Нет необходимости думать или заботиться о том, имеет ли смысл удалять узлы в этом случае, потому что это просто происходит автоматически каждый раз.

Обратите внимание, что я не говорю, что этот код (даже близко) на 100% идеален. С достаточно современным компилятором, чтобы поддерживать его, вы почти наверняка захотите, чтобы он был шаблоном, позволяющим хранить произвольный тип, и использовать unique_ptr и make_unique вместо необработанного указателя и необработанного new. К сожалению, у меня нет другого выбора, кроме как пропустить их, так как я уверен, что Turbo C++ не поддерживает unique_ptr, и сомневаюсь, что он также поддерживает шаблоны. Для реального использования это также должно включать в себя конструктор копирования и оператор присваивания, поэтому назначение и копирование связанных списков будет работать правильно (в нынешнем виде любой из них обычно приводит к проблемам, поскольку в конечном итоге он пытается уничтожить узлы в связанный список дважды).

Последнее замечание: конечно, обычно вам не следует писать собственный код связанного списка. Но когда/если у вас есть причина написать контейнер (или что-то подобное), он должен, так сказать, навести порядок в своем собственном беспорядке. Одной из сильных сторон C++ является детерминированное разрушение; используй это.

22.01.2014
Новые материалы

Как создать диаграмму градиентной кисти с помощью D3.js
Резюме: Из этого туториала Вы узнаете, как добавить градиентную кисть к диаграмме с областями в D3.js. Мы добавим градиент к значениям SVG и применим градиент в качестве заливки к диаграмме с..

Я хотел выучить язык программирования MVC4, но не мог выучить его раньше, потому что это выглядит сложно…
Просто начните и учитесь самостоятельно Я хотел выучить язык программирования MVC4, но не мог выучить его раньше, потому что он кажется мне сложным, и я бросил его. Это в основном инструмент..

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

Объяснение документов 02: BERT
BERT представил двухступенчатую структуру обучения: предварительное обучение и тонкая настройка. Во время предварительного обучения модель обучается на неразмеченных данных с помощью..

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

Работа с цепями Маркова, часть 4 (Машинное обучение)
Нелинейные цепи Маркова с агрегатором и их приложения (arXiv) Автор : Бар Лайт Аннотация: Изучаются свойства подкласса случайных процессов, называемых дискретными нелинейными цепями Маркова..

Crazy Laravel Livewire упростил мне создание электронной коммерции (панель администратора и API) [Часть 3]
Как вы сегодня, ребята? В этой части мы создадим CRUD для данных о продукте. Думаю, в этой части я не буду слишком много делиться теорией, но чаще буду делиться своим кодом. Потому что..


Для любых предложений по сайту: [email protected]