• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

question-closed Dziwny crash przy dereferencji iteratorów

Object Storage Arubacloud
0 głosów
283 wizyt
pytanie zadane 9 września 2016 w C i C++ przez criss Mędrzec (172,590 p.)
zamknięte 9 września 2016 przez criss

Program mi się crashuje w momencie w którym nie powinien. Co dziewniejsze - wcześniej się to działo tylko w binarce skompilowanej w trybie Debug albo odpalając pod debugerem. W Release wszystko działało (zamierzałem potem się tym zająć) - aż do dzisiaj. Teraz w Release też się sypie. Debuger twierdzi vector iterator not dereferencable. Kompiluje msvc. Pod gcc tego nie było, aczkolwiek gcc w ogóle nie kompilowałem do wersji (?) debug.

Kod:

   std::vector<float> xVec, yVec, zVec;
   auto comp = [](float& a, float& b)->bool { return a < b; };

   for(auto& mesh : m_meshes)
   {
      std::pair<float, float> minMaxX, minMaxY, minMaxZ;
      std::tie(minMaxX, minMaxY, minMaxZ) = mesh.getMinMaxCoords();

      xVec.push_back(minMaxX.first);
      xVec.push_back(minMaxX.second);

      yVec.push_back(minMaxY.first);
      yVec.push_back(minMaxY.second);

      zVec.push_back(minMaxZ.first);
      zVec.push_back(minMaxZ.second);
   }
   
   auto x = std::minmax_element(xVec.begin(), xVec.end(), comp);
   auto y = std::minmax_element(yVec.begin(), yVec.end(), comp);
   auto z = std::minmax_element(zVec.begin(), zVec.end(), comp);

   m_size = {
               *x.second - *x.first,
               *y.second - *y.first,
               *z.second - *z.first
            }; 

Dla jasności:

  • To metoda obliczająca rozmiar (minimalne rozmiary prostopadłościanu w jaki można zmieścić model) modelu. 
  • Mesh::getMinMaxCoords wyszukuje wierzchołki najbardziej oddalone (w obie strony) na osiach x, y, z w obrębie mesha (jakby części modelu) i zwraca odpowiedni std::tuple.
  • m_size to glm::vec3. Zwykły wrapper na 3 floaty, nic szczególnego.

To tak, żeby kod był jasny, ale to nie ma związku z błędem. 

std::minmax_element wyszukuje w obrębie [first, last), więc nie tyka iteratora .end(). Vectory (w sensie kontenery ofc) istnieją w chwili dereferencji, więc nie rozumiem o co może chodzić. Dla pewności spróbowałem użyć minmax_element na .begin() ; .end() - 1 (chodzi mi o zakres) na wypadek gdyby microsoftowi sie coś pomyliło z implementacją i funkcja by szukała w [first, last], ale nic to nie dało - dokładnie to samo.

Jakieś pomysły o co może chodzić?

btw właśnie sobie uświadomiłem, że ta lambda jest niekonieczna, ale nieważne

komentarz zamknięcia: Standardowo - jestem idiotą. Nieważne.
komentarz 9 września 2016 przez draghan VIP (106,230 p.)
http://en.cppreference.com/w/cpp/algorithm/minmax

Czy sekcja "Notes" na dole strony nie wyjaśnia powodu błędu? Tylko rzucam pomysłem, bez analizy kodu.
komentarz 9 września 2016 przez criss Mędrzec (172,590 p.)
Patrzysz na nie tą funkcję, ja tutaj używam minmax_element :P
komentarz 9 września 2016 przez draghan VIP (106,230 p.)
Racja, racja. Przez poranny pośpiech nawet nie analizowałem kodu no i się pomyliłem w wyszukiwarce na cppreference.com. Przepraszam.

Uprościłem sobie Twój kod do użycia tylko po iksach, żeby igreki i zety nie zaciemniały. Zrobiłem makiety typów vec3 oraz Mesh, żeby dało się to skompilować. Błędu nie dostrzegam - zarówno w trakcie wykonywania aplikacji, jak również w kodzie. Musi tu spojrzeć ktoś lepszy ode mnie. Zagadaj na ircu, może adrian17 pomoże.
komentarz 9 września 2016 przez draghan VIP (106,230 p.)
Jakie jest rozwiązanie problemu?
komentarz 9 września 2016 przez criss Mędrzec (172,590 p.)
edycja 9 września 2016 przez criss

Nie pisałem, bo nie jest w ogóle związane z programowaniem :|

Sklonowałem z gh swoje repo, a że gh (albo w ogóle git? nie znam sie) nie łapie plików obj, to nie złapał też mojego modelu który był właśnie w pliku obj (obj tworzony przez kompilator i obj dla modeli to oczywiście dwa różne formaty plików ale mają te same nazwy)... Najpewniej po prostu w folderze z Debug exe nie było wcześniej pliku z modelem - teraz nie jestem w stanie tego sprawdzić.

Nie wiem dlaczego nie zapisywało mi logu o nie błędzie w ładowaniu modelu do pliku, bo powinno, potem ogarne. Gdyby to zrobiło wcześniej bym ogarnął co sie dzieje.

W każdym razie skoro model nie został załadowany, to m_meshes (std::vector) był pusty a wyniku tego te trzy vectory były też puste i stąd problem z dereferencją iteratorów (wszystkie wskazywały na .end())... No taka głupia sprawa :D

edit: chociaż nie, na Debug cały czas sie sypie, ale to pewnie dlatego, że Assimp (ładuje nim modele) jest skompilowany do Release. Jeszcze sprawdze. Najwyżej kiedyś jeszcze wróce z problemem.

Anyway dzięki za poświęcony czas i zainteresowanie...

1 odpowiedź

0 głosów
odpowiedź 9 września 2016 przez MetRiko Nałogowiec (37,110 p.)

Nie rozumiem jednej rzeczy (możliwe, że przez niedokładne przeanalizowanie kodu):
"funkcja" comp przyjmuje dwa float'y, a ty do funkcji std::minmax_element wrzucasz do porównania iteratory (iterator != float). W końcu .begin() i .end() zwracają iteratory, a nie wartości. Możliwe, że jestem w błędzie.. ale to chyba tutaj leży problem.

komentarz 9 września 2016 przez criss Mędrzec (172,590 p.)
Nie, tak powinno być. Minmax_element używa sobie lambdy w odpowiedni sposób (przesyłając to na co wskazują iteratory). Możesz spojrzeć w dokumentację. Inna sprawa, że ta lambda w ogóle jest niepotrzebna bo jest przecież zdefiniowany operator < dla dwóch floatow. Potem się jej pozbede bo pisze z telefonu.

Podobne pytania

+2 głosów
3 odpowiedzi 531 wizyt
pytanie zadane 11 kwietnia 2021 w C i C++ przez Daaa22 Dyskutant (8,250 p.)
0 głosów
1 odpowiedź 421 wizyt
pytanie zadane 19 marca 2019 w C i C++ przez Hiskiel Pasjonat (22,830 p.)
0 głosów
1 odpowiedź 285 wizyt
pytanie zadane 19 października 2016 w C i C++ przez MasterKiller Nowicjusz (120 p.)

92,570 zapytań

141,422 odpowiedzi

319,643 komentarzy

61,958 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...