Мне было просто любопытно, будет ли этот код вызывать множественные утечки памяти или будет ли он корректно очищен.
Node *newNode;
for (int i = 0; i < 10; i++)
{
newNode = new Node();
}
delete newNode;
Очевидно, что код ничего не делает, но он помогает мне объяснить мой сценарий. Я выделяю память 10 раз, и когда я удаляю указатель, оставляя 9 сирот? Или я повторно использую то же место, которое было выделено, и правильно удаляю сироту?
Заранее спасибо!
Да, это утечка памяти. Когда вы делаете:
newNode = new Node();
Вы переопределяете указатель так, чтобы он указывал на вновь выделенную память, фактически теряя способ адресации ранее указанной памяти для ее удаления.
Поэтому, когда вы выходите из цикла, newNode
указатель указывает на последнюю (десятую) память /Node
, Когда ты delete newNode
Вы удаляете только эту память. У вас больше нет способа, которым delete
другие.
Как Чжи Ван указал, что вы можете использовать некоторую форму умного указателя (unique_ptr
или же shared_ptr
в C ++ 11 например). Эти интеллектуальные указатели в основном являются обертками вокруг обычных указателей, которые имеют дополнительную семантику, предотвращающую этот вид утечек. Если вы используете один из них, память / объекты будут автоматически освобождены, когда они выйдут из области видимости (по окончании текущей итерации for
цикл в этом случае).
тем не мение, Я не думаю, что это решит вашу ситуацию в этом случае. Я сомневаюсь, что вы хотите delete
10 объектов, как только вы их создадите. Скорее, вы, вероятно, хотите хранить эти объекты в контейнере, как std::vector
или, по крайней мере, иметь массив указателей, указывающих на каждый из этих выделенных экземпляров. Таким образом, вы будете иметь объекты вокруг (что, я считаю, то, что вы хотите, так как вы создаете их вообще), а также способ удалить их позже.
Да, ваш код утечки памяти. Ваше первое предположение о поведении правильное. Этот код
Node *newNode;
for (int i = 0; i < 10; i++)
{
newNode = new Node(); // allocate memory 10 times in a loop...
}
delete newNode; // ... but free the memory only once!
выделяет память 10 раз ( new
оператор внутри for
цикл), но освобождает память, используемую только один из этих объектов ( delete
оператор внизу). Естественно, это оставляет остальные 9 объектов сиротами — память, которую они потребляют, по-прежнему выделяется, но теперь у вас нет возможности получить к ней доступ, чтобы освободить ее. Это, конечно, само определение утечки памяти.
В отличие от этого кода
Node *newNode;
for (int i = 0; i < 10; i++)
{
newNode = new Node(); // allocate memory 10 times in a loop
delete newNode; // ... and free the memory each time
}
не теряет память, потому что есть один вызов delete
за каждый звонок new
, Это большое правило, которое вы должны иметь в виду: если вы не соответствуете каждый звонок new
с соответствующим вызовом delete
, у вас будет утечка памяти.
Или, может быть, даже лучше, когда вы работаете в C ++, никогда не используйте сырые указатели. Стандартная библиотека C ++ предоставляет несколько отличных классов-обёрток, которые реализуют идиому RAII для указателей, что гарантирует правильное уничтожение указанных объектов и, следовательно, освобождение используемой ими памяти. Начните свое исследование либо в вашем любимая книга C ++, или на Википедия.