Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.142.136.159] |
|
Страницы: (2) 1 [2] все ( Перейти к последнему сообщению ) |
Сообщ.
#16
,
|
|
|
Режь её, как льва в Африке, чего столько времени терпеть. Мы для платы, или плата для нас ? Если поиски такие долгие, ножом всё и закончится.. |
Сообщ.
#17
,
|
|
|
Цитата Qraizer @ Внутри цикла ты делаешь delete узлу списка, а позже в инкременте итератора обращаешься к его полю next. да это я уже понял Добавлено Цитата shm @ for (NodeIterator tmp; headIterator != NodeIterator(); ) { tmp = headIterator; ++headIterator; delete tmp.getNode(); } бинго shm работает Добавлено спс |
Сообщ.
#18
,
|
|
|
Когда-то делал я свой список с итераторами. До дома дойду, выложу решение. Скажу лишь, что у меня есть обертка для элемента списка (шаблонный класс с пользовательским полем data) и отдельно класс списка, который всем этим рулит. Добавлено Цитата ЫукпШ @ Режь её, как льва в Африке, чего столько времени терпеть. Да нашел уже. Методом пайки-выпайки элементов. |
Сообщ.
#19
,
|
|
|
мля сам же это решение выше написал а вот перевести на итератор не смог
Добавлено спс shm выручил а то башка уже болит |
Сообщ.
#20
,
|
|
|
Как и обещал выкладываю свою реализацию из ядра своей игрушечной ОС. Не претендую на правильность реализации. Писал это дело очень давно я (еще в школе учился ), качество кода так себе. Но у меня удаление объекта (если мы храним в списке указатели на него) не рушит ссылки.
template< typename T > class klist { struct _node_item { T item; _node_item *next; _node_item *prev; }; public: class iterator { _node_item *_pitem; friend class klist; public: const bool operator!=(const iterator &it) const { return (_pitem != it._pitem); } T& operator*() const { return _pitem->item; } const iterator& operator++(int) { _pitem = _pitem->next; return *this; } const iterator& operator++() { _pitem = _pitem->next; return *this; } }; private: static const size_t _default_alloc_areas_size = 4; static const size_t _default_max_size = 0x100000; static const size_t _default_base_size = 0x10; kvector<_node_item*> _alloc_areas; _node_item *_free_list; iterator _begin_item; iterator _end_item; iterator _end_item_ret; size_t _cur_ar_size; size_t _max_size; void _add_free_region(size_t ar_size) { _node_item *ar = new _node_item[_cur_ar_size]; _node_item *it, *end = ar + ar_size - 1, *tmp; for(it = ar; it < end; ) { tmp = it++; tmp->next = it; } it->next = NULL; _free_list = ar; _alloc_areas.push_back(ar); } void _init(size_t base_size, size_t max_size) { _cur_ar_size = base_size; _max_size = max_size; _begin_item._pitem = NULL; _end_item._pitem = NULL; _end_item_ret._pitem = NULL; _add_free_region(_cur_ar_size); } _node_item *_alloc_item() { if(_free_list == NULL) { _cur_ar_size <<= 1; if(_cur_ar_size > _max_size) _cur_ar_size = _max_size; _add_free_region(_cur_ar_size); } _node_item *item = _free_list; _free_list = item->next; return item; } public: klist() : _alloc_areas(_default_alloc_areas_size) { _init(_default_base_size, _default_max_size); } ~klist() { typename kvector<_node_item*>::iterator it = _alloc_areas.begin(); for( ; it < _alloc_areas.end(); it++) delete[] *it; } klist(size_t base_size, size_t max_size = _default_max_size) : _alloc_areas(_default_alloc_areas_size) { _init(base_size, max_size); } void push_back(const T &item) { _node_item *pitem = _alloc_item(); pitem->item = item; if(_end_item._pitem == NULL) { pitem->prev = NULL; pitem->next = NULL; _end_item._pitem = pitem; _begin_item._pitem = pitem; } else { pitem->next = NULL; pitem->prev = _end_item._pitem; _end_item._pitem->next = pitem; _end_item._pitem = pitem; } } const iterator& begin() const { return _begin_item; } iterator& begin() { return _begin_item; } const iterator& end() const { return _end_item_ret; } iterator erase(iterator &it) { _node_item *cur = it._pitem; _node_item *next = cur->next; cur->next = _free_list; _free_list = cur; if(_end_item._pitem == cur) _end_item._pitem = NULL; if(it._pitem == _begin_item._pitem) { _begin_item._pitem = next; return _begin_item; } else { _node_item *prev = cur->prev; prev->next = next; if(next != NULL) next->prev = prev; iterator next_it; next_it._pitem = next; return next_it; } } void clear() { for(_node_item *area : _alloc_areas) delete[] area; _alloc_areas.clear(); _init(_default_base_size, _default_max_size); } void clear_no_free() { for(auto it = begin(); it != end(); it = erase(it)); } }; |
Сообщ.
#21
,
|
|
|
Цитата shm @ Как и обещал выкладываю свою реализацию из ядра своей игрушечной ОС. Не претендую на правильность реализации. Писал это дело очень давно я (еще в школе учился ), качество кода так себе. Но у меня удаление объекта (если мы храним в списке указатели на него) не рушит ссылки. shm будет чем заняться на досуге Добавлено немного изменил код добавил operator++(int) и т.о. вызов упростился до while (nodeIterator != NodeIterator()){ delete (nodeIterator++).getNode(); } |
Сообщ.
#22
,
|
|
|
что то с std::for_each я туплю
std::for_each(nodeIterator, NodeIterator(), [&nodeIterator](const Node& ){ delete (nodeIterator++).getNode(); }); не работает иксепщн ловит Добавлено вот так пробовал тоже иксепшен std::for_each(nodeIterator, NodeIterator(), []( Node& node){ Node* tmp = node.next; delete &node; node = *tmp; }); |
Сообщ.
#23
,
|
|
|
Цитата Cfon @ delete (nodeIterator++).getNode(); Это тоже самое, что: delete nodeIterator.getNode() ++nodeIterator; Добавлено Цитата Cfon @ вот так пробовал тоже иксепшен А это вообще не должно работать, т.к. Цитата Cfon @ идет по твоему самодельному итератору, а не по ссылке на node. for_each |
Сообщ.
#24
,
|
|
|
Цитата shm @ Цитата Cfon @ delete (nodeIterator++).getNode(); Это тоже самое, что: delete nodeIterator.getNode() ++nodeIterator; нет не тоже в operator++(int) возвращается копия предыдущего NodeIterator NodeIterator operator++(int) { NodeIterator tmp(*this); node = node->next; return tmp; } Добавлено Цитата shm @ А это вообще не должно работать, т.к. Цитата Cfon @ идет по твоему самодельному итератору, а не по ссылке на node.for_each тогда как надо то? Добавлено вот так цикл висит while (nodeIterator != NodeIterator()){ delete nodeIterator.getNode(); ++nodeIterator; } |
Сообщ.
#25
,
|
|
|
Цитата Cfon @ нет не тоже for_each каждый раз дергает operator++ со своим внутренним итератором, который к твоему nodeIterator отношения не имеет. Добавлено Цитата Cfon @ тогда как надо то? Я не знаю, что ты хочешь. Добавлено Человек, который разводил плату, не знал какую модель памяти использовать, поэтому "предусмотрел" два варианта. Но в итоге все благополучно забылось и запаяли оба. |
Сообщ.
#26
,
|
|
|
shm я тебе говорил про то что след вариант тоже удаляет и все работает нормально!
while (nodeIterator != NodeIterator()){ delete (nodeIterator++).getNode(); } ты мне написал что это тоже самое что while (nodeIterator != NodeIterator()){ delete nodeIterator.getNode(); ++nodeIterator; } но это не так Добавлено Цитата shm @ Я не знаю, что ты хочешь. ОМГ shm я хочу тоже что и раньше удалить эти ноды но уже через алгоритм std::for_each Добавлено вот такой вариант не работает std::for_each(nodeIterator, NodeIterator(), []( Node& node){ Node* tmp = node.next; delete &node; node = *tmp; }); Добавлено вот этот вариант не надо больше обсуждать std::for_each(nodeIterator, NodeIterator(), [&nodeIterator](const Node& ){ delete (nodeIterator++).getNode(); }); я уже понял что Цитата shm @ for_each каждый раз дергает operator++ со своим внутренним итератором, который к твоему nodeIterator отношения не имеет. |
Сообщ.
#27
,
|
|
|
Цитата Cfon @ вот такой вариант не работает std::for_each(nodeIterator, NodeIterator(), []( Node& node){ Node* tmp = node.next; delete &node; node = *tmp; // <-- тут не верно }); кажись понял в чем дело, но проблема не решилась короче в последней строчке ошибка, надо бы изменить т.о. for_each(nodeIterator, NodeIterator(), []( Node& node){ Node* tmp = node.next; delete &node; &node = tmp; //<-- тут }); но и это не корректно т.к. происходит попытка изменить ссылку node чего делать нельзя делаю вывод что удалить через std::for_each не получиться по причине передачи node по ссылке! |
Сообщ.
#28
,
|
|
|
Цитата Cfon @ ты мне написал что это тоже самое что Во-первых я про цикл не упоминал. Во-вторых да, некорректно я написал. Я имел ввиду все целиком с for_each. Если будешь дальше из себя строить шибко умного, то подсказывать не буду. Добавлено Цитата Cfon @ shm я хочу тоже что и раньше Я понятия не имею, что ты хотел раньше. Цитата Cfon @ удалить эти ноды но уже через алгоритм std::for_each Удалить можно, но хороших решений не вижу. Добавлено Node *old = nullptr; std::for_each(nodeIterator, NodeIterator(), [&old]( Node& node) { delete old; old = &node; }); delete old; |
Сообщ.
#29
,
|
|
|
Ну извратов много можно придумать:
struct FakeIterator : public NodeIterator { FakeIterator() : NodeIterator() { } FakeIterator(Node* _node): NodeIterator(_node) { } FakeIterator& operator++() { auto node = getNode(); NodeIterator::operator++(); delete node; return *this; } }; //... FakeIterator nodeIterator(head); std::for_each(nodeIterator, FakeIterator(), []( Node& node) { }); |
Сообщ.
#30
,
|
|
|
Цитата shm @ Во-первых я про цикл не упоминал. Во-вторых да, некорректно я написал. Я имел ввиду все целиком с for_each. Если будешь дальше из себя строить шибко умного, то подсказывать не буду. shm сори Добавлено Цитата shm @ Удалить можно, но хороших решений не вижу. Node *old = nullptr; std::for_each(nodeIterator, NodeIterator(), [&old]( Node& node) { delete old; old = &node; }); delete old; struct FakeIterator : public NodeIterator { FakeIterator() : NodeIterator() { } FakeIterator(Node* _node): NodeIterator(_node) { } FakeIterator& operator++() { auto node = getNode(); NodeIterator::operator++(); delete node; return *this; } }; //... FakeIterator nodeIterator(head); std::for_each(nodeIterator, FakeIterator(), []( Node& node) { });; да уж изврат Добавлено тогда по стринке в цикле Добавлено не лень.. это его обязаность |