QList<double*>, implicit sharing, Liste abbauen

Alles rund um die Programmierung mit Qt
Antworten
bobcat
Beiträge: 125
Registriert: 21. April 2010 14:51

QList<double*>, implicit sharing, Liste abbauen

Beitrag von bobcat »

In meiner Anwendung benutze ich eine Anzahl von double Arrays konstanter Länge, die ich in QList<double*> zusammenfasse. Unterwegs kopiere ich mal von einer QList<double*> in eine andere, und ich frage mich gerade, ob ich danach die QList auch wieder korrekt abbaue. Konkret sieht das in einer vereinfachten Version so aus:

Code: Alles auswählen

QList<double*> dataList;
QList<double*> tempList;
double* element;

// Eigentliche Datenliste erstellen
for ( int i = 0; i < anzahl; i ++ ) {
    element = new double[laenge];
    fillWithData(element);
    dataList.append(element);
}

// Datenliste in temporäre Liste kopieren
for ( int i = 0; i < anzahl; i ++ )
    tempList.append( dataList.at(i) );

// Jetzt Datenliste löschen und die temporäre Liste wieder in die Datenliste kopieren. 

// Version 1
dataList.clear();
dataList = tempList;

// Version 2
clearVectorList( dataList );
dataList = tempList;


void clearVectorList(QList<double*>& list) {
    for ( int i = 0; i < list.size(); ++i)
        delete[] list[i];
    list.clear();
}

Ich habe den Eindruck, dass beide Versionen das gewünschte Ergebnis (d.h. ursprüngliche Daten in dataList vorhanden, Daten nur einmal im Speicher vorhanden, tempList kann mit clear abgebaut werden, ohne dataList zu beeinflussen) bringen, bin mir aber nicht sicher, ob ich das richtig verstanden habe.

Nachdem ich in der zweiten for Schleife die tempList gefüllt habe, sind die Daten noch nicht dupliziert worden, ich habe jetzt lediglich 2 QList mit den Zeigern auf die jeweils gleichen double Arrays, oder? Führe ich nun in Version 2 das clearVectorList(...) aus, dann wird zwar dataList vollständig abgebaut, die Daten können somit aber nicht mehr von tempList geshared werden und werden deshalb dabei neu angelegt?

Im Gegensatz dazu werden in Version 1 nur die Zeiger in dataList gelöscht und die eigentlichen Daten (das double Array) werden nach der Zuweisung dataList = tempList; wieder geshared?

Weiß jemand, was da genau hinter den Kulissen passiert?
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Re: QList<double*>, implicit sharing, Liste abbauen

Beitrag von Christian81 »

1. Warum überhaupt dobule* und nicht double
2. Bei der zweiten Variante crasht es wenn Du auf einen der double - Pointer in tempList/dataList zugreifen willst weil der Speicher ja freigegeben wurde. Das hat aber nichts mit implicit sharing zu tun ...
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
bobcat
Beiträge: 125
Registriert: 21. April 2010 14:51

Re: QList<double*>, implicit sharing, Liste abbauen

Beitrag von bobcat »

Christian81 hat geschrieben:1. Warum überhaupt dobule* und nicht double
Naja, ich weiss zu Anfang nicht, wie viele double Arrays ich brauche, das ist von Fall zu Fall verschieden. Die Arrays lege ich dynamisch während der Laufzeit an. Zudem kann auch die Länge der Arrays variieren, zwar nicht während der Laufzeit, aber ich muss bei Programmstart überprüfen, wie lange die Arrays nun sein müssen.
Wäre denn QList<double[]> auch eine Möglichkeit und würden die QList dann tatsächlich mit den gesamten Arrays hantieren statt nur mit den double Zeigern?
Christian81 hat geschrieben:2. Bei der zweiten Variante crasht es wenn Du auf einen der double - Pointer in tempList/dataList zugreifen willst weil der Speicher ja freigegeben wurde. Das hat aber nichts mit implicit sharing zu tun ...
Stimmt, kann ich jetzt bei mir auch so reproduzieren. Das bedeutet, dass in meinem Fall die double Zeiger in den QList implicit-sharing unterliegen, nicht aber die Daten der Arrays, auf die sie zeigen, oder?
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Re: QList<double*>, implicit sharing, Liste abbauen

Beitrag von Christian81 »

Ein Array von doubles - QVector<double> z.B.

Natürlich werden nur die Daten implizit geshared - in diesem Fall sind die Daten eben Pointer auf doubles
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
kater
Beiträge: 306
Registriert: 29. Dezember 2009 01:13
Wohnort: Darmstadt

Re: QList<double*>, implicit sharing, Liste abbauen

Beitrag von kater »

Wie wäre es mit QPointer? Dann gibt es zumindest keinen Segfault wenn du auf ein bereits gelöschtes Element zugreifst
bobcat
Beiträge: 125
Registriert: 21. April 2010 14:51

Re: QList<double*>, implicit sharing, Liste abbauen

Beitrag von bobcat »

Sind beides gute Tipps! Letztlich benutze ich double* aus historischen Gründen ... als ich anfing, die Anwendung zu programmieren war mir nicht klar, wie die Performance aussieht, wenn ich z.B. QVector<double> oder QPointer benutze. Meine QList hat üblicherweise 30.000 Elemente, können aber auch mal deutlich mehr sein. Meine Variante mit den double* läuft auch stabil, mir ging es in erster Linie darum, besser zu verstehen, was da genau abläuft.
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Re: QList<double*>, implicit sharing, Liste abbauen

Beitrag von Christian81 »

Die Performance von QList<double*> sollte schlechter sein als von QList<double> da bei jedem Zugriff noch der Pointer derefenziert werden muss. Bei QList<double> (was sich wie QVector<double> verhält) muss bei 30000 Elementen ein linearer Speicherbereich von 30000*8Byte = 240KB vorliegen. Allerdings belegen bei 64Bit die double-Pointer auch 8Byte/Element... also brauchst Du im Endeffekt den doppelten Speicher und bist langsamer -> schmeiss den Pointer raus wenn Du auf Performance schauen musst.
QList verhält sich übrigens bei PODs genauso wie QVector/std::vector und nicht wie man vermuten könnte wie std::list. Siehe auch Doku.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
bobcat
Beiträge: 125
Registriert: 21. April 2010 14:51

Re: QList<double*>, implicit sharing, Liste abbauen

Beitrag von bobcat »

Ich meine, hier liegt noch ein kleines Missverständnis vor, was den Anwendungsfall betrifft. Meine double* zeigen nicht auf einen double Wert, sondern auf ein double Array, siehe Code oben:

Code: Alles auswählen

element = new double[laenge];
Daher ja auch die Konstruktion, würde ich auf einen der genannten Vorschläge umsteigen, bräuchte ich wohl sowas wie
QList< QVector<double> >
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Re: QList<double*>, implicit sharing, Liste abbauen

Beitrag von Christian81 »

Ja, da müsste man sich dann auch nicht mehr um die Pointer Gedanken machen :)
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
Antworten