Loading...

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

niagara avatar niagara 22 Точки

C++ Advanced - 02. Memory Management -Task 2 - Remove Invalid

Здравейте, имам въпрос относно освобождаването на динамична памет на елемент от list. Когато използваме erase, паметта освобождава ли се, и ако не, как можем да я освободим при триенето на невалидния елемент?

Ето го и моят код: https://pastebin.com/JEM2s77m

Също така се чудя дали memory leak може да отговаря за runtime errors в Judge Test 8-10. Ще съм благодарна ако някой ми подскаже къде се дъня.

0
C++ Programming
georgi.stef.georgiev avatar georgi.stef.georgiev 921 Точки
Best Answer

 

Здравей,

Не, erase не освобождава памет - реално погледнато erase при контейнерите не знае какъв е типа на нещото, което маха от списъка - просто го маха, без да прави каквото и да е за него.

Правилно си се ориентирала, че при твоя код това води до memory leak, защото erase-ваш елемент, който е единствения pointer към памет, която е заделена с new - съответно тази памет никога не се освобождава (представи си, че изтриваш номера на някого от телефона си - номера сочи към него, но като махнеш номера от телефона, телефонът ти не отива да затрие истинския човек зад този номер, просто забравя, че го има този човек). Най-вероятно това причинява и другите грешки (8-10 тест) - системата не винаги може да засече правилно превишаване на лимита преди програмата сама да се счупи заради проблеми с алокацията.

Освобождаването става по същия начин, както при нормален указател - пишеш delete и подаваш указателя. Синтаксисът е малко по-странен, защото указателят е сочен от итератор. Съответно трябва да дереференцираме итератора, за да получим указателя, който да изтрием:

if ( ... ) {
  delete *it;
  it = companies.erase(it);
}

Ако това те обърква като код, помисли как би го разбила на отделни променливи:

if ( ... ) {
  Company* c = *it;
  delete c;
  companies.erase(it);
}

В авторското решение това с Company* c = *it се прави като първа стъпка в тялото на цикъла - така if-овете и изтриването са по-прости, защото работим директно с указателя, а не с итератор към указателя.

Като допълнение: това, че delete-ваме указател, сочен от итератор, това няма никакво влияние върху самия итератор (даже и указателя не се променя, само сочената памет се освобождава) - ако някой си изхвърли телефона, това няма автоматично да промени номера в твоя указател за него - просто ако се опиташ да му се обадиш ще имаш "недефинирано поведение".

Поздрави,

Жоро

1
Можем ли да използваме бисквитки?
Ние използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Можете да се съгласите с всички или част от тях.
Назад
Функционални
Използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Използваме „сесийни“ бисквитки, за да Ви идентифицираме временно. Те се пазят само по време на активната употреба на услугите ни. След излизане от приложението, затваряне на браузъра или мобилното устройство, данните се трият. Използваме бисквитки, за да предоставим опцията „Запомни Ме“, която Ви позволява да използвате нашите услуги без да предоставяте потребителско име и парола. Допълнително е възможно да използваме бисквитки за да съхраняваме различни малки настройки, като избор на езика, позиции на менюта и персонализирано съдържание. Използваме бисквитки и за измерване на маркетинговите ни усилия.
Рекламни
Използваме бисквитки, за да измерваме маркетинг ефективността ни, броене на посещения, както и за проследяването дали дадено електронно писмо е било отворено.