Seite 1 von 1

Großes Problem mit QList's

Verfasst: 2. November 2005 16:26
von prof_maad
Hallo alle miteinander,

ich sitze derzeit unter Zeitdruck an einem Prog, in dem ich an einer Stelle mit mehreren QList's hantieren muss.

Meine Hauptklasse enthält eine QList vom Typ "song", eine Struktur:

Code: Alles auswählen

struct song
{
    QLabel *title;
    int position;
    int counter;
    bool jumped;
};

Code: Alles auswählen

QList<song> *songlist;
QList wird initialisiert:

Code: Alles auswählen

songlist = new QList<song>();
Dann werden alle Elemente mit Standart-Werten besetzt:

Code: Alles auswählen

void favs::initPlayList(int count)
{
     for(int i=0;i<count;i++)
     {
         song tmpSong;
         QString tmpString = "Song " + QString::number(i);
         
         tmpSong.title    = new QLabel(tmpString);
         tmpSong.position = i;
         tmpSong.jumped   = false;
         tmpSong.counter  = rand()%100;
         
         songlist->append(tmpSong);
     }
}
So, dann habe ich eine Funktion, die diese QList in ein Layout einbaut:

Code: Alles auswählen

void favs::fillGrid()
{
     playlistLayout->addWidget(new QLabel("<b>Nr</b>"),0,0);
     playlistLayout->addWidget(new QLabel("<b>Song</b>"),0,1);
     playlistLayout->addWidget(new QLabel("<b>Counter</b>"),0,2);
     playlistLayout->addWidget(new QLabel("<b>Jumped?</b>"),0,3);
     
     for(int i=0;i<songlist->size();i++)
     {
         playlistLayout->addWidget(new QLabel(QString::number(i)),i+1,0);
         playlistLayout->addWidget(songlist->at(i).title,i+1,1);
         playlistLayout->addWidget(new   QLabel(QString::number(songlist->at(i).counter)),i+1,2);
         
         QString tmpString = "";
         if(songlist->at(i).jumped)
         {
             tmpString = tr("jumped");
         }
         else
         {
             tmpString = tr("played");
         }
         
         playlistLayout->addWidget(new QLabel(tmpString),i+1,3);
     }
}


So, und dann habe ich eine Funktion, die nach einem bestimmten Muster aus diese QList eine neue erzeugt:

Code: Alles auswählen

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 = new QList<song>(*first20);
     fillGrid();
}
So, dass war erstmal der Code.

Jetzt zum Problem:

1. Die generierte Liste verweist manchmal auf ungültige Speicherpositionen vom Typ 0x00000000

2. Beim Einfügen der neuen QList in das Layout mit "fillGrid()" bleiben immer 5,6 oder 7 Elemente leer.

Wenn jemand ne Idee hat, woran das liegen könte, wäre das klasse.

Danke im Voraus,

Prof. MAAD

Verfasst: 2. November 2005 17:42
von Christian81
Ich würde nicht QList<song> *songlist; sondern QList<song> songlist; verwenden damit das blödsinnige new (und delete, das du übrigens vergessen hast) zu vermeiden...
Aufgrund der komischen Pointer würde ich sagen, dass " tmpList2 = tmpList; " auch nicht das ist was du willst ... dort werden nur die Ptr zugewiesen, nicht der Inalt!

Verfasst: 2. November 2005 18:02
von prof_maad
Danke erstmal.

Dass das mit tmpList2 = tmpList etc. nicht funzt, habe ich mir auch schon gedacht. Habe das deßhalb jetzt anders gemacht.

Ich habe auch die gesamte Funktion "generateList()" nochmal neu geschrieben und dabei vereinfacht.

Hier die neue Funktion:

Code: Alles auswählen

void favs::generateList()
{
     QList<song> *tmpList = new QList<song>;                //temporäre Arbeitskopie
     QList<song> *first20 = new QList<song>;                //Liste der ersten 20 Titel
     QList<song> *top10 = new QList<song>;
     QList<song> *top5 = new QList<song>;
     int act_haufigkeit = -1;                               //aktuelle Häufigkeit
     int act_position = 0;                                  //aktuelle Position in Liste
     int last_haufigkeit = usageCountSpin->value()+1;       //letzte Häufigkeit
     
     //TEMP
     for(int i=0;i<songlist->size();i++)
     {
         tmpList->append(songlist->at(i));
     }
     //TMP END
     //10 meistgehörte Stücke ermitteln
     for(int j=0;j<10;j++)
     {
         int i=0;
         for(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;
             }
         }
         top10->append(tmpList->at(act_position));
         last_haufigkeit = act_haufigkeit;
         act_haufigkeit = 0;
         act_position = 0;
     }
     
     //5 zufällige Titel daraus auswählen
     for(int i=0;i<5;i++)
     {
             int rnd = rand()%(top10->size()-1);
             top5->append(top10->at(rnd));
             top10->erase(top10->begin()+rnd);
     }
     
     //15 Titel zufällig in Playlist ordnen
     for(int i=0;i<15;i++)
     {
         int rnd = rand()%tmpList->size();
         first20->append(tmpList->at(rnd));
         tmpList->erase(tmpList->begin()+rnd);
     }
     
     //Die 5 Favorites per Zufall dazwischen schieben
     for(int i=0;i<5;i++)
     {
         int rnd = rand()%first20->size();
         first20->insert(rnd,top5->at(i));
         QMessageBox::critical(this,QString::number(rnd),first20->at(rnd).title->text());
     }
     
     //Liste speichern
     songlist->clear();
     
     //TEMP
     for(int i=0;i<first20->size();i++)
     {
         songlist->append(first20->at(i));
     }
     //TMP END
     
     fillGrid();
}
Diese liefert nun keine ungültigen Speicheradressen mehr, allerdings habe ich immer noch das komische Problem, dass "fillGrid" sehr merkwürdige Ergebnisse liefert:
- obwohl "songlist" 20 Elemente hat, füllt er das GridLayout mit 30 Elementen
- des weiteren fehlen immer 5-7 Elemente (Nur das Label fehlt, die Ints sind da!)

So, falls jemand da ne Idee hat wäre ich sehr dankbar.

Danke im Voraus und Ciao,

Prof. MAAD