std::list::clear + _HAS_ITERATOR_DEBUGGING =access violation

0

wygląda na to, że w visualowym STLu w std::list<>::clear mam do czynienia z jakimś bugiem, no chyba, że ja coś źle robię, ale w sumie tu się chyba nie da nawet nic źle robić xd

do rzeczy,
wywołanie clear na jednym z moich kontenerów listy pluje access violationem, kiedyś myślałem że metody clear to się nie da zepsuć, bo niby jak? nie przyjmuje nic z zewnątrz, ale jak zwykle okazuje się, że nie ma rzeczy niemożliwych :>

przyczyna jakaś jest, bo mam 2 kontenery list (poza tym przecież już wiele razy w innych projektach używałem STLowej listy i zawsze dobrze było) i tylko na jednym występuje problem, czyli to jakiś dziwny konkretny przypadek tylko dla tej feralnej jednej listy, przyczyny nie widzę, to raczej nic z zewnątrz, wygląda na to, że wewnętrznie coś źle działa

w dodatku źle działa nie samo clear, tylko to co jest pod #definem _HAS_ITERATOR_DEBUGGING, to pewnie jakiś visualowy wynalazek do debugowania iteratorów, wygląda na to, że sam potrzebuje debugowania
pod Release, gdy _HAS_ITERATOR_DEBUGGING nie jest ustawiony, rzecz jasna clear śmiga, tylko pod Debug, gdy sam nie ustawię #define _HAS_ITERATOR_DEBUGGING 0, problem ma miejsce

zresztą samemu można sobie to z bliska obejrzeć, zamieszczam projekt (do kompilacji wymagany SDK Direct): http://lublin.webd.pl/crayze/Enginev02.zip

ustaliliśmy, że to dzieje się na visualu z sp1, nie wiem jak na innych wersjach (oczywiście nie dotyczy innych IDE, bo ich STLe nie mają konstrukcji _HAS_ITERATOR_DEBUGGING)

chętnych, znających wewnętrzne bebechy visualowego STLa zapraszam do pobrania, ja nie mam zamiaru babrać się w tym, a w sumie ciekawy jestem co jest przyczyną, czy czy to coś z moją klasą, którą przechowuje lista, czy wewnętrznie spierniczony jest _HAS_ITERATOR_DEBUGGING
po otwarciu projektu będzie zaznaczony brakpointem o który clear się rozchodzi

0

Glupie pytanie, ale jestes pewien ze nigdzie nie masz jakiegos blednego wskaznika, ktory nadpisuje pamiec tam gdzie nie powinien? Bo takie kwiatki to raczej nie powinny normalnie wystepowac.
Dasz rady odtworzyc to w jakims minimalnym przykładzie?

0
othello napisał(a)

Glupie pytanie, ale jestes pewien ze nigdzie nie masz jakiegos blednego wskaznika, ktory nadpisuje pamiec tam gdzie nie powinien? Bo takie kwiatki to raczej nie powinny normalnie wystepowac.

mi się wydaje, że wszystko jest dobrze, kod pisałem na spokojnie i uważnie, pod debuggerem nic się nie dzieje i wszystko wygląda dobrze, tak samo jak działa,
aczkolwiek tego czy gdzieś jest jakiś błąd nie można wykluczyć i nie da się być tego pewnym, na razie poza tą anomalią nic niezwykłego się nie dzieje

othello napisał(a)

Dasz rady odtworzyc to w jakims minimalnym przykładzie?

tzn?, no odtworzyć to nie bardzo, bo tylko w tym konkretnym projekcie się tak dzieje,

jeśli problemem jest brak SDK Direct i nie chce ci się tego grubasa ściągać, to załączam include'y i 2 potrzebne liby: http://lublin.webd.pl/crayze/sdkdirect.zip

0

HAS_ITERATOR_DEBUGGING to flaga ktora wlacza runtime-check'i wewnatrz kontenerow STL, sprawdzajace co chwila takie rzeczy jak np. czy iterator ktorego wlasnie *'kujesz nie jest aby z poza kontenera, czy tez czy iterator ktorego uzywasz nie jest aby zerwany.

jesli CLEAR wpakowuje sie na ten test, to najprawdopodobniej oznacza, ze, gdy juz wywolasz clear i cos-wewnatrz-clear zacznie iterowac po elementach je zwalniac (->destruktory!), to podczas tego usuwania dzieje sie cos, co powoduje usuniecie ("ponowne"!) jakiegos elementu w tym kontenerze.

jesli tak jest, to to-co-sie-odpalilo-przy-okazji zepsuje kolejnosc iteracji oryginalnego clear (zawieszonego na chwile), i po powrocie do tegoż clear, przy probie kontynuowania iteracji, clear moze sie wpakowac w ... element/iterator już nieistniejacy (ale ktory istnial na starcie!). ewentualnie vice-versa, patrz taki przypadek (malorealny, ale obrazowy!):

klasa X ma w sobie *-na-kontener<auto_ptr<X>>, nazwany 'magazynWKtorymLeze'
destruktor X'a sprawdza czy X jest wewnatrz {magazynWKtorymLeze} i jesli jest, usuwa go

czyli - jak bierzesz jakiegos dowolnego X*'a, delete'ujesz go - super, X sie sam 'wyrejestrowuje'.

ale co sie stanie jak zrobisz kontener.clear zeby wszystkie Xy wywalic?
clear zacznie iterowac, wezmie iterator na pierwszy element, wywola jego destr (ow wyrejestruje element), poczym sprobuje ++iter, co wywali ów test gdyz ... na przyklad dla kontener=vector, iter juz nie jest prawidlowy! jest zerwany. zawartosc kontenera sie zmienila, przealokowano, papa..

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