Форум «Всё о Паскале» _ Ада и другие языки _ Список. Удаление
Автор: Fanat 23.01.2008 17:27
Список содержит указатели на элементы. Необходимо удалить i-ый элемент списка, при этом удалить и сам элемент. Я делаю так
it += Index; delete *it; m_List.erase(it);
Всё работает если Index = 0, или если нет строки delete *it. А если удалить элемент с индексом больше 0 (меньше размера списка), то при следующем проходе по списку вылетает ошибка по доступу к памяти...как правильно сделать?..
Автор: volvo 23.01.2008 17:31
Если список - это std::list, то достаточно одного erase(it)... delete здесь ни при чем совершенно.
Автор: Fanat 23.01.2008 17:38
Цитата(volvo @ 23.01.2008 13:31)
Если список - это std::list, то достаточно одного erase(it)... delete здесь ни при чем совершенно.
Да это std::list, но вылетают потери памяти если удалять просто erase(it)...а если с delete *it то нет...
Автор: Michael_Rybak 23.01.2008 17:52
Цитата
Если список - это std::list, то достаточно одного erase(it)... delete здесь ни при чем совершенно.
volvo, там не объекты, а указатели, Fanat хочет и объект удалить, и указатель на него.
Fanat, попробуй заменить it += index циклом. т.е. пробегай по списку вручную до нужного элемента.
Автор: Fanat 23.01.2008 18:02
Цитата(Michael_Rybak @ 23.01.2008 13:52)
Fanat, попробуй заменить it += index циклом. т.е. пробегай по списку вручную до нужного элемента.
Так на самом деле работает...но был перегружен оператор + таким же самым образом... http://forum.pascal.net.ru/index.php?showtopic=21198... Ну и пишу я соответственно не += ,а в нужном месте (it + Index).
Автор: volvo 23.01.2008 18:20
Fanat, это твой тип, или что-то готовое (я про то, на что указывает указатель)?
Автор: Fanat 23.01.2008 18:31
Цитата(volvo @ 23.01.2008 14:20)
Fanat, это твой тип, или что-то готовое (я про то, на что указывает указатель)?
Мой тип.
Автор: Michael_Rybak 23.01.2008 18:59
Цитата
Так на самом деле работает...но был перегружен оператор + таким же самым образом...
Тогда тести для index = 1, сравнивай с перегрузкой и без (одновременно), смотри адреса и выясняй, где расхождение.
Автор: volvo 23.01.2008 20:24
Цитата
Мой тип.
Можно посмотреть, как заполняется список?
Автор: Fanat 23.01.2008 20:33
Цитата(volvo @ 23.01.2008 16:24)
Можно посмотреть, как заполняется список?
int __fastcall TTrfObjectList::add(ILXListItem* aItem) { m_List.push_back(aItem); return m_List.size(); };
for(int i = 0; i < c_nNumberOfStartElems; i++) { ILXListItem* pItem = new TTrfListItem(i*10*pow(-1,i)); m_pList->add(pItem); }
Вот так он заполняется...этого хватит или ещё чтото выложить?..хотя я уже решил везде заменить перегруженную операцию на пробег по итератору в цикле, так то она работает(далко только перегрузку конечно...=()...так что можно не искать ошибку...
Автор: volvo 23.01.2008 21:47
Fanat, я не совсем понимаю, откуда у тебя берутся leak-и... Вот смотри:
class TMyList: public list<int*> { friend TMyList::iterator& operator + (TMyList::iterator &it, int index) { for(; index; --index) ++it; return it; }
for(int i = 0; i < 20; i++) { int *p = new int(i); myList.push_back(p); }
myList.erase_element(5);
for(TMyList::iterator it = myList.begin(); it != myList.end(); it++) { Memo2->Lines->Add(IntToStr(*(*it))); } }
Код аналогичен твоему, правда? Ну, за исключением некоторых мелочей... Только почему-то у меня CodeGuard молчит... Попробуй у себя прогнать это, будет ругаться?
Автор: Fanat 23.01.2008 22:33
Цитата(volvo @ 23.01.2008 17:47)
Ну, за исключением некоторых мелочей...
У себя прогнал...В общем мелочью оказалась следующее: Я писал
delete *(it + aIndex); m_List.erase(it + aIndex);
А ты
delete *(it = (it + aIndex)); m_List.erase(it);
Вот в твоём варианте всё работает хорошо...а в моём даже до ликов не доходит... ошибка вылетает...