Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. International
  3. Polish
  4. [solved] aplikacja Qt GUI - "upływ" danych?

[solved] aplikacja Qt GUI - "upływ" danych?

Scheduled Pinned Locked Moved Polish
19 Posts 4 Posters 8.8k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    apb1
    wrote on last edited by
    #1

    Cześć.
    Mam do napisania aplikację okienkową, która kataloguje zdjęcia według różnych parametrów exif. Polega to na tym, że użytkownik podaje lokalizację folderu ze zdjęciami, program odczytuje wybrane dane, tworzy z nich listę plików i wyświetla. Istnieje możliwość sortowania po każdym parametrze, rosnąco lub malejąco. Program uruchamia się, wyświetla listę plików poprawnie, pierwsze sortowanie też działa, dalej ilość pozycji się zmniejsza, aż w końcu program przestaje działać. Czasem działaja jedno sortowanie, czasem kilka. Efekt końcowy jest zawsze taki sam. Upływ danych i zawieszenie się aplikacji - czasem od razu się zawiesza. Co robię źlę?

    Link do plików z programem:
    "program exiv":https://docs.google.com/file/d/0B9NtEembQQvWOHJVcXhEZFlEeGM/edit?usp=sharing

    Dziękuję za pomoc :)

    1 Reply Last reply
    0
    • sierdzioS Offline
      sierdzioS Offline
      sierdzio
      Moderators
      wrote on last edited by
      #2

      Użyj valgrinda, lub nawet zwykłego debuggera żeby zobaczyć gdzie tracisz pamięć. Prawdopodobnie gdzieś coś mieszasz we wskaźnikach.

      (Z(:^

      1 Reply Last reply
      0
      • A Offline
        A Offline
        apb1
        wrote on last edited by
        #3

        Debuger pokazuje, że coś jest nie tak w pliku sortowanie.cpp, 92 linijka: poprzedni->next = NULL;
        Przeanalizowałem działanie całego programu i nie mam pojęcia dlaczego tam jest źle. Macie może jakieś pomysły?

        1 Reply Last reply
        0
        • sierdzioS Offline
          sierdzioS Offline
          sierdzio
          Moderators
          wrote on last edited by
          #4

          Zdefiniuj "coś jest nie tak". Ustawianie wskaźnika na NULL na pewno nie jest złe samo w sobie, ale z reguły wcześniej dobrze jest zniszczyć ten obiekt (delete). To jednak bardzo zależy od implementacji (czasem dany wskaźnik jest tylko lokalny i nie ma potrzeby niszczyć obiektu, albo jest to QObjekt i niszczeniem zajmie się meta object system).

          (Z(:^

          1 Reply Last reply
          0
          • A Offline
            A Offline
            apb1
            wrote on last edited by
            #5

            Ale skoro zniszczę obiekt to później nie będę mógł się już odwołać do tego miejsca w liście i program praktycznie w ogóle nie działa. No, chyba, że coś mylę...

            Gdy przestaje działać pojawia się komunikat: Otrzymano sygnał. Podproces zatrzymany, ponieważ otrzymał on sygnał z systemu operacyjnego. Nazwa sygnału: SIGSEGV. Znaczenie sygnału: Segmentation fault.

            Kompilator przenosi mnie do modułu sortowanie.cpp i wskazuje żółtą strzałką na linijkę 92, czyli: poprzedni->next = NULL;

            Jeśli zmienię wątek, to wskazuje na coś takiego: 0x77a700fd <+0x02d3> sub $0x14,%esp

            Jeśli przełączę w tryb debugowania na instrukcjach:
            @
            92 poprzedni->next = NULL;
            0x4035f4 <+0x011f> mov -0x1c(% ebp),% eax
            0x4035f7 <+0x0122> movl $0x0,0x38(% eax)@

            (Błąd w pogrubionej linijce, też wskazywany przez żółtą strzałkę.)

            Wcześniej napisałem aplikację konsolową i wszystko było ok, teraz po podlączeniu nie działa.

            bq. niszczeniem zajmie się meta object system

            Chodzi o destruktor?

            1 Reply Last reply
            0
            • A Offline
              A Offline
              apb1
              wrote on last edited by
              #6

              Nie wiem dlaczego, ale ucina mi część wiadomości.

              Teraz działa, wystarczyło dodać pause po %. Proszę o skasowanie tego postu :)

              1 Reply Last reply
              0
              • sierdzioS Offline
                sierdzioS Offline
                sierdzio
                Moderators
                wrote on last edited by
                #7

                Ok czyli jesteś w sytuacji gdzie nie trzeba nic niszyczyć ;) Nie zaglądam do twojego kodu, także w gruncie rzeczy zgaduję co się dzieje.

                Jeśli tylko poprzedni->next nie jest prywatny (a nie jest, bo by cię kompilator zakrzyczał), to NULL zawsze ustawić możesz. Sprawdź czy gdzieś potem w kodzie nie próbujesz odczytać tego wskaźnika: system wykrzaczy się SIGSEGV właśnie wtedy, gdy próbujesz dostać się do zmiennej wskazywanej przez pointer, a tam nic nie ma (NULL).

                Czyli jeśli dobrze rozumiem, to w debugowaniu program się krzaczy, ale w release działa, tylko ubywa pozycji na liście? Może ubywa dlatego że kasujesz obiekty "next" właśnie?

                (Z(:^

                1 Reply Last reply
                0
                • A Offline
                  A Offline
                  apb1
                  wrote on last edited by
                  #8

                  W trybie release (to ten zwykły przysisk play, ctrl+R, zgadza się?) program też w pewnym momencie przestaje działac i wtedy wywala "Program exif_okienkowo.exe przestał działać".

                  To moja funkcja sortująca:

                  @lista * sortuj_rosnaco(lista * akt_lst, int pole){
                  lista * max, *poczatek, *tmp_poczatek, *poprzedni;
                  int ten_sam;
                  max = akt_lst;
                  poczatek = akt_lst;
                  tmp_poczatek = akt_lst;

                  while(tmp_poczatek->next!=NULL){
                      max = tmp_poczatek;
                      akt_lst = tmp_poczatek;
                      ten_sam = 1;
                      while (akt_lst!=NULL){
                          if (porownaj_elementy(max, akt_lst, pole)==1){
                              max = akt_lst;
                              ten_sam--;
                          }
                          akt_lst = akt_lst->next;
                      }
                      if (ten_sam == 1){
                          if(tmp_poczatek != poczatek){
                              tmp_poczatek = tmp_poczatek->next;
                              poprzedni = wyszukaj_poprzedni(poczatek, max); //wyciagnac mina
                              poprzedni->next = max->next; // zalatac dziure
                              max->next = poczatek; // wstawienie na poczatek
                              poczatek = max; // zapisanie nowego poczatku
                          }else{
                              tmp_poczatek = tmp_poczatek->next;
                          }
                      }else{
                          poprzedni = wyszukaj_poprzedni(poczatek, max); //wyciagnac mina
                          poprzedni->next = max->next; // zalatac dziure
                          max->next = poczatek; // wstawienie na poczatek
                          poczatek = max; // zapisanie nowego poczatku
                      }
                  }
                  // trick dla wstawienia ostatniego na poczatek
                  poprzedni = wyszukaj_poprzedni(poczatek,tmp_poczatek);
                  poprzedni->next = NULL;
                  tmp_poczatek->next = poczatek;
                  poczatek = tmp_poczatek;
                  
                  return poczatek;
                  

                  }@
                  Błąd w lini 38. Z każdym kolejnym wywołaniem ubawa pozycji w liście aż w końcu (podejrzewam) program odwołuje się do pola, które "nie istnieje".

                  1 Reply Last reply
                  0
                  • sierdzioS Offline
                    sierdzioS Offline
                    sierdzio
                    Moderators
                    wrote on last edited by
                    #9

                    Zamień linie 37 i 38 albo całkiem skasuj linię 38.

                    (Z(:^

                    1 Reply Last reply
                    0
                    • A Offline
                      A Offline
                      apb1
                      wrote on last edited by
                      #10

                      Zamiana lini nic nie daje.
                      Jeśli skasuję linię 38 to już przy próbie pierwszego sortowanie program się wiesza.
                      Dzięki za pomoc :)

                      1 Reply Last reply
                      0
                      • A Offline
                        A Offline
                        ariwez
                        wrote on last edited by
                        #11

                        Zwracanie wskaźników przez funkcję to śliska rzecz, naprawdę ;]

                        funkcja wyszukaj_poprzedni może zwrócić NULL a Ty sobie beztrosko linijkę dalej wywołujesz:

                        @poprzedni->next = max->next;@

                        albo

                        @poprzedni->next = NULL;@

                        Wypadaloby w każdym przypadku sprawdzić czy przypadkiem wskaźnik nie jest nullem, a ryzyko crasha się zminimalizuje.

                        1 Reply Last reply
                        0
                        • A Offline
                          A Offline
                          apb1
                          wrote on last edited by
                          #12

                          Dlaczego zwracanie wskaźników przez funckję to śliska rzecz? Jak robić to inaczej?

                          Poprawiłem, teraz wygląda to tak:

                          @Lista * sortuj_rosnaco(Lista * akt_lst, int pole){
                          Lista * max, *poczatek, *tmp_poczatek, *poprzedni;
                          int ten_sam;
                          max = akt_lst;
                          poczatek = akt_lst;
                          tmp_poczatek = akt_lst;

                          while(tmp_poczatek->next!=NULL){
                              max = tmp_poczatek;
                              akt_lst = tmp_poczatek;
                              ten_sam = 1;
                              while (akt_lst!=NULL){
                                  if (porownaj_elementy(max, akt_lst, pole)==1){
                                      max = akt_lst;
                                      ten_sam--;
                                  }
                                  akt_lst = akt_lst->next;
                              }
                              if (ten_sam == 1){
                                  if(tmp_poczatek != poczatek){
                                      tmp_poczatek = tmp_poczatek->next;
                                      poprzedni = wyszukaj_poprzedni(poczatek, max); //wyciagnac max
                                      if (poprzedni!=NULL){ // tutaj zmiana nr 1
                                          poprzedni->next = max->next; // zalatac dziure
                                          max->next = poczatek; // wstawienie na poczatek
                                          poczatek = max; // zapisanie nowego poczatku
                                      }
                                  }else{
                                      tmp_poczatek = tmp_poczatek->next;
                                  }
                              }else{
                                  poprzedni = wyszukaj_poprzedni(poczatek, max); //wyciagnac max
                                  if (poprzedni!=NULL){ // tutaj zmiana nr 2
                                      poprzedni->next = max->next; // zalatac dziure
                                      max->next = poczatek; // wstawienie na poczatek
                                      poczatek = max; // zapisanie nowego poczatku
                                  }
                              }
                          }
                          // trick dla wstawienia ostatniego na poczatek
                          poprzedni = wyszukaj_poprzedni(poczatek,tmp_poczatek);
                          if (poprzedni!=NULL) {// tutaj zmiana nr 1
                              poprzedni->next = NULL;
                              tmp_poczatek->next = poczatek;
                              poczatek = tmp_poczatek;
                          }
                          
                          return poczatek;
                          

                          }@
                          Niestety program dalej nie działa poprawnie...

                          1 Reply Last reply
                          0
                          • A Offline
                            A Offline
                            ariwez
                            wrote on last edited by
                            #13

                            bq. Dlaczego zwracanie wskaźników przez funckję to śliska rzecz? Jak robić to inaczej?

                            Właśnie dlatego że wszędzie trzeba później sprawdzać poprawność wskaźnika, inaczej to można zwracać referencję do obiektu.

                            Odapliłem Twój program i jest crash hell, cokolwiek nie kliknę to wywala się apka ;]

                            Chociażby w tym miejcu:
                            @ if (el1->nazwa >= el2->nazwa) @

                            Dobrze by było jakbyś zapoznał się ze standardowymi kontenerami np. "QList":http://qt-project.org/doc/qt-4.8/qlist.html, bo Twoja implementacja listy to po pierwsze odkrywanie koła na nowo, a po drugie to zamota ze wskaźnikami powoduje totalny brak stabilności.

                            1 Reply Last reply
                            0
                            • A Offline
                              A Offline
                              apb1
                              wrote on last edited by
                              #14

                              bq. Odapliłem Twój program i jest crash hell, cokolwiek nie kliknę to wywala się apka ;]

                              Jeśli nie poda się prawidłowej ścieżki do zdjęć to program się wywala od razu. A dane poprawnie odczytywać będzie chyba tylko z 40D.

                              bq. Dobrze by było jakbyś zapoznał się ze standardowymi kontenerami np. QList [qt-project.org], bo Twoja implementacja listy to po pierwsze odkrywanie koła na nowo, a po drugie to zamota ze wskaźnikami powoduje totalny brak stabilności.

                              Chyba wchodzimy na zbyt wysoki poziom. :) Nie ma już czasu na przebudowanie całego projektu, może uda się znaleźć jeszcze błąd. W aplikacji konsolowej wszystko działało.

                              1 Reply Last reply
                              0
                              • A Offline
                                A Offline
                                apb1
                                wrote on last edited by
                                #15

                                Udało mi się naprawić program. Błąd był zupełnie gdzie indziej, wystarczyło dopisać jedną linijkę.

                                Mam jeszcze pytanie. Czy da się zrobić i czy dużo jest roboty z tym, aby użytkownik wybierał lokalizację z wykorzystaniem czegoś w rodzaju menadżera windowsa? Tak jak podaję się lokalizację do zainstalowania w programach.

                                Dzięki za pomoc :)

                                1 Reply Last reply
                                0
                                • A Offline
                                  A Offline
                                  Alek Śmierciak
                                  wrote on last edited by
                                  #16

                                  Czy chodzi Ci o wybieranie ścieżki (folderu) lub pliku? Jeśli tak, to "QFileDialog":http://qt-project.org/doc/qt-5.0/qtwidgets/qfiledialog.html.

                                  1 Reply Last reply
                                  0
                                  • A Offline
                                    A Offline
                                    apb1
                                    wrote on last edited by
                                    #17

                                    O coś takiego mi chodziło. Jak znajdę chwilę czasu to postaram się dołożyć. Dziękuję serdecznie!

                                    1 Reply Last reply
                                    0
                                    • A Offline
                                      A Offline
                                      Alek Śmierciak
                                      wrote on last edited by
                                      #18

                                      Powodzenia. Pamiętaj, aby w temacie dopisać w nazwie "[solved]" na znak rozwiązania problemu - rozumiem, że upływu danych już nie ma. :-)

                                      1 Reply Last reply
                                      0
                                      • A Offline
                                        A Offline
                                        apb1
                                        wrote on last edited by
                                        #19

                                        Nie, nie ma. Miałem błąd w module mainwindow. Wywołując funkcję sortującą przekazywałem zawsze ten sam wskaźnik, tak więc stopniowo ginęły dane, które były wcześniej na liście dynamicznej. Dopisanie linijki załatwiło sprawę. Później usunąłem tą i kilka innych linijek, zmieniłem nazwę wskaźnika na inny (prawdłowy) i śmiga aż miło. Dziękuję raz jeszcze. :)

                                        1 Reply Last reply
                                        0

                                        • Login

                                        • Login or register to search.
                                        • First post
                                          Last post
                                        0
                                        • Categories
                                        • Recent
                                        • Tags
                                        • Popular
                                        • Users
                                        • Groups
                                        • Search
                                        • Get Qt Extensions
                                        • Unsolved