STL list - gwarancja braku zmiany adresów elementów

0

Witam,

Chcę przechowywać w liście pewne złożone obiekty. W czasie pracy programu z tych obiektów będzie korzystała inna biblioteka i dlatego chciałbym mieć gwarancję, że jakiekolwiek operacje zmiany tej listy (oprócz destrukcji elementu oczywiście ;) ) nie spowoduje zmiany adresu jakiegokolwiek elementu.
Wydaje mi się oczywiste, że lista tak działa, no ale jako początkujący programista chciałbym usłyszeć od kogoś doświadczonego, że taka sytuacja nie ma szans się zdarzyć.

Pozdrawiam

0

jeśli będziesz operował na wskaźnikach do tych obiektów, to mogą być przechowywane kopie tych wskaźników, na nich wykonywane operacje itd. więc nie widzę potrzeby martwienia się o obiekt do czasu gdy sam nie postanowisz go usunąć. Chyba, że nie zrozumiałem problemu(?)

0

Nie do końca zrozumiałeś, ale dzięki za odpowiedź. Może problem opiszę bardziej szczegółowo, aby wyjaśnić dlaczego zależy mi, aby obiekty nie zmieniały swojego adresu.

Program konkretnie będzie współpracował z symulatorem (układów elektronicznych). Współpraca ta jest możliwa dzięki callbackom. Symulator w czasie symulacji wywołuje funkcję składową klasy o nazwie "transaktor", która ma następującą postać:

 static void input_ready_cb(void* context)

W argumencie przesyłam wskaźnik do konkretnego obiektu tej klasy i ten obiekt następnie wykonuje pewne operacje. I teraz chodzi o to, że takich transaktorów chcę mieć kilka w takim kontenerze "list". Przy inicjalizacji każdego transaktora podaję symulatorowi jego adres (ta informacja zostaje w symulatorze do końca symulacji) i żeby symulacja się nie posypała adresy transaktorów nie mogą się zmienić. Dlatego kombinowanie z jakimiś tablicami wskaźników wydaje mi się nieadekwatne do problemu, bo to nie ja korzystam z tych obiektów tylko symulator na który nie mam wpływu.

Mam nadzieję, że to rozjaśni sprawę.

0

po pierwsze: cokolwiek ponizej w moim poscie przeczytasz, jest podyktowane "dokładnością" opisów, tekstów, definicji i itp. Osobiście jestem przekonany, że Twoja std::list gwarantuje Ci niezmienność adresów elementów tak długo, jak element siedzi na liscie.

Jedną z gwarancji jaką dostajesz, w przeciwienstwie np. do vector'a, jest to, że jeśli kiedykolwiek do jakiekogolkwiek elementu listy pobierzesz 'iterator', to nie wazne co bedziesz robil na liscie, dopoki element wskazywany przez iterator dalej bedzie logicznie -na- liscie, to ten iterator bedzie ważny . Niestety, wazne jest sformulowanie, iterator.

Z iteratora mozesz wyciagnac wskaznik na element - &*iterator - i to w zasadzie powinno Ci wystarczyc.
Niestety nie przypominam sobie, aby stl::list gwarantowało niezmiennosc adresu elementow. Wydaje mi sie, ze jedyne gwarancje tyczyly sie operacji dokonywanych na elementach poprzez iteratory. Jednak rowniez wydaje mi sie ze by bylo niezwykle dziwne gdyby wewnetrzny kontener listy przealokowywal lub przenosil elementy w momencie wstawiania/usuwania. Nie taki jest "interfejs" listy. Lista ma gwarantowac pewne konkrene, "listowe", złożoności obliczeniowe metod insert/fetch/delete, czego przy przenoszeniu/przealokowywaniu elementow w tych momentach po prostu by sie nie dalo uzyskac..

http://www.cplusplus.com/reference/stl/list/ 1)
http://www.cppreference.com/wiki/container/list/start 2)
http://www.sgi.com/tech/stl/List.html 3)

  1. erase: "and, unlike in these, all of the previously obtained iterators and references remain valid after the erasing operation and refer to the same elements they were referring before (except, naturally, for those referring to erased elements)." -- dopisek and references sugeruje ze wskazniki i referencje rowniez pozostaja wazne!
  2. erase: "No iterators, except to the removed elements, are invalidated." -- ani mrumru o wskanzikach/referencjach
  3. "[3] A similar property holds for all versions of insert() and erase(). List<T, Alloc>::insert() never invalidates any iterators, and list<T, Alloc>::erase() only invalidates iterators pointing to the elements that are actually being erased."

Tak wiec, poza pierwszym źródłem, które jest dobre, ale nie jest "znaczące", cała reszta mówi o iteratorach, czyli fakty czy adres elementu pozostanie taki sam, wyglada na, niestety, implementation-specific. To znaczy, ze jesli jakas implementacja listy bedzie miala hiperinteligentne iteratory ktore na biezaco dynamicznie wyliczaja wskazniki, to sama lista moglaby przenosic elementy, i takie zachowanie pozostaloby w zgodzie ze specyfikacja.. Nie mniej, i tak sadze, ze jest to bardzo malo prawdopodobne, zwyczajowo przyjmuje sie ze pointer/referecja na element zyje tak dlugo jak zwiazany z nia iterator jest ważny..

Przekopie sie jeszcze przez kilka dokumnetow, moze cos znajde wiecej.

1

iso1998

  • w definicjach "iterator" nie ma mowy o jego zwiazku z adresem elementu, poza "Since iterator is an abstraction of pointer", co nie definiuje wymagań w tym sensie

ale za to w definicji std:
"insert/push_front/push_back (...) Notes: Does not affect the validity of iterators and references (..)"
"erase/pop_front/pop_back/clear (...) Effects: Invalidates only the iterators and references to the erased elements (..)"

wiec gwarancję masz, przynajmniej wg. iso1998, jednak musisz uwazac na rożne metody, np. SPLICE anulowuje wszystko w obrębie listy "przejmowanej".

przejrzalem tez std2003 z tym samym wynikiem. draftu 2008 szczerze mowiac, juz mi sie nie chce:}

0

final draft 2011 mówi tak samo.

0

No tak, nie pomyślałem aby zajrzeć do samego standardu. Bardzo Wam dziękuję za pomoc :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1