Pointer-Problem



  • Hallo alle miteinander,

    ich sitze derzeit an einem Prog mit Qt.

    An einer Stelle habe ich derzeit ein Problem, denn das Programm beendet manchmal mit einem Speicherzugriffsfehler.

    Also, zuerst einmal habe ich folgende Struktur und folgende Liste erstellt:

    struct song
    {
        QLabel *title;
        int position;
        int counter;
        bool jumped;
    };
    
    QList<song> *songlist;
    

    Danach die Liste initialisiert:

    songlist = new QList<song>;
    

    So, und dann habe ich da eine ziemlich lange Funktion, die auf Basis dieser Liste nach einem bestimmten Muster eine neue erzeugt:

    void favs::generateList()
    {
         QList<song> *tmpList = new QList<song>;                //temporäre Arbeitskopie
         QList<song> *tmpList2 = new QList<song>;               //2. temporäre Arbeitskopie
         QList<song> *first20 = new QList<song>;                //Liste der ersten 20 Titel
         tmpList = songlist;
         int haufigste[10] = {0,0,0,0,0,0,0,0,0,0};             //die häufigsten 10 Songs
         int favorites[5] = {0,0,0,0,0};                        //die Favorites-First-Einträge
         int act_haufigkeit = -1;                                //aktuelle Häufigkeit
         int act_position = 0;                                  //aktuelle Position in Liste
         int last_haufigkeit = usageCountSpin->value()+1;       //letzte Häufigkeit
         int positionen[20] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
         int apos = 0;
         //10 meistgehörte Stücke ermitteln
         for(int j=0;j<10;j++)
         {
             for(int i=0;i<tmpList->size();i++)
             {
                 if((tmpList->at(i).counter > act_haufigkeit)&&(tmpList->at(i).counter < last_haufigkeit))
                 {
                     act_position = i;
                     act_haufigkeit = tmpList->at(i).counter;
                 }
             }
             haufigste[j]=act_position;
             last_haufigkeit = act_haufigkeit;
             act_haufigkeit = 0;
             act_position = 0;
         }
    
         //5 zufällige Titel daraus auswählen
         bool done[10] = {false,false,false,false,false,false,false,false,false,false};
         bool found = false;
         for(int i=0;i<5;i++)
         {
             while(!found)
             {
                 int rnd = rand()%9;
                 if(!done[rnd])
                 {
                     favorites[i]=haufigste[rnd];
                     found =     true;
                     done[rnd] = true;
                 }
             }
             found = false;
         }
    
         //15 Titel zufällig in Playlist ordnen
         tmpList2 = tmpList;
         for(int i=0;i<15;i++)
         {
             int rnd = rand()%tmpList2->size();
             first20->append(tmpList2->at(rnd));
             tmpList2->erase(tmpList2->begin()+rnd);
         }
    
         //Die 5 Favorites per Zufall dazwischen schieben
         for(int i=0;i<5;i++)
         {
             int rnd = rand()%(14+i);
             first20->insert(rnd,tmpList->at(favorites[i]));
         }
    
         //Liste speichern
         songlist = first20;
         fillGrid();
    }
    

    Das Problem ist nun, dass, wahrscheinlich in der unteren Hälfte der Funktion, es dazu kommt (manchmal), dass ein Element der Liste auf einmal nicht mehr gültig ist, also auf einen ungültigen Speicherbereich verweist.

    Hat jemand eine Idee, wodurch das zu stande kommt?

    Vielen Dank im Voraus,

    Ciao,

    Prof. MAAD



  • Ich denke, dass das Problem die rand-Funktion ist.
    Denn weder die noch du kontrolliert nicht den Wertebereich dieser Funktion.
    int rnd = rand()%tmpList2->size();
    Hier könnte durchaus 0 rauskommen und dein nachfolgendes at()
    geht auf etwas nicht definiertes.

    Analoges gilt für die Zeilen:
    int rnd = rand()%(14+i);
    first20->insert(rnd,tmpList->at(favorites[i]));

    Ich würde mir an deiner Stelle mal alle rnd-Werte entweder auf dem
    Bildschirm oder in einer Datei protokollieren lassen.



  • Also meiner Meinung nach dürfte das kein Problem sein, denn fängt die Nummerierung der Listen nicht mit Null an.
    Demnach müsste doch liste->at(0) etwas gültiges liefern, oder liege ich da falsch?

    Danke im Voraus und Ciao,

    Prof. MAAD



  • Was sagt denn valgrind dazu?



  • Also mal generell würde ich mich fragen wo die deletes zu den ganzen new's sind.
    Ist zwar wahrscheinlich nicht das Problem aber afaik ist QList nicht von QObject abgeleitet. Weiterhin besagt die Doku zum = Operator von QList: "Assigns other to this list and returns a reference to this list". Assigns klingt für mich nicht nach kopiert den Inhalt einer Liste (wonach deine Verwendung eigentlich aussieht).



  • assign heißt in dem Zusammenhang "zuordnen" 😉


Anmelden zum Antworten