что происходит с неиспользуемой памятью в C ++ - PullRequest
4 голосов
/ 18 июня 2011

У меня были некоторые проблемы с программированием, и я столкнулся с одной -

Реализовать алгоритм для удаления узла в середине одного связанного списка, предоставляется только доступ к этому узлу.

Пример:
Ввод: узел "c" из связанного списка a->b->c->d->e
Результат: ничего не возвращается, но новый связанный список выглядит как a->b->d->e

Решение этой проблемы - просто скопировать данные из следующего узла в этот узел, а затем удалить следующий узел.

Приведенное выше решение учитывает язык Java как язык программирования. Мне интересно, что будет с содержимым удаленного узла? Будет ли отличаться его судьба в Java и C ++? А также, я думаю, что идеальный ответ на этот вопрос должен также освободить память удаленного узла. Как мы это делаем в C ++?

Ответы [ 5 ]

4 голосов
/ 18 июня 2011

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

Да.

Как нам это сделать в c ++?

С оператором delete.

Возможно, вы забегаете вперед, если работаете над списками ссылок и не знаете об операторе delete. Вы не хотите пропускать шаги при изучении C или C ++; это отрубит тебе голову позже.

3 голосов
/ 18 июня 2011

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

В C ++ с умными указателями освобождение памяти гарантируется, как только объект больше не может быть адресован.По сути, он работает почти как сборщик мусора в Java, если у вас нет круговых графов ссылок.

Если вы не используете умные указатели, вам придется вручную вызывать delete c (или free(c)).Если вы этого не сделаете, вашей программе будет выделена память, которую она больше никогда не сможет использовать.

1 голос
/ 18 июня 2011

В ответ на заголовок вопроса «Что происходит с неиспользуемой памятью в C ++», память помечается как нераспределенная диспетчером памяти, но, вероятно, не возвращается в операционную систему в этот момент (если вообще когда-либо) для эффективности.Отмена осуществляется с помощью ключевого слова delete

. Для вашего конкретного примера (поспешно сшитого вместе):

Предположим, такой узел, как

struct Node
{
    Node* next;
} head;   

//Later...

Node* pred = head; //Where head is the start of the list
while((pred->next != NULL) && (pred->next != c))
{
   pred  = pred->next;          
}

Node* toDelete = pred->next;
Node* newSuccessor = toDelete->next;

/*
  This is the moment when the memory is considered freed. 
  free() should only be used if the node was allocated with malloc()
*/
delete toDelete; 

pred->next = newSuccessor; 
1 голос
/ 18 июня 2011

Ну, это не совсем то, что вы делаете в C ++. Что вы должны делать / что происходит:

  1. Удалить память, на которую указывает c.
  2. Скопируйте указатель в память из d в c.
  3. Скопируйте указатель на e из d в c.

Теперь мы фактически вывели d из списка и заставили c вести себя так, как если бы это было d. И, наконец, если d тоже где-то выделен и должен быть удален отдельно, вы удаляете его после 3.

Почему 1? Потому что в Java, если объект больше не используется, он автоматически собирает мусор. В C ++ это не так.

0 голосов
/ 18 июня 2011

В Java это в конечном итоге будет собираться как мусор.В C ++ вы должны освободить его явно, используя ключевое слово delete.

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

...