2016-12-04 3 views
-1

Der Staat docs erstellt befreien the following:Wie QByteArray mit fromRawData()

QByteArray nehmen nicht das Eigentum an Daten, so dass die QByteArray destructor wird nie die Rohdaten löschen, wenn auch der letzte QByteArray Bezug zu Daten wird zerstört.

In diesem Sinne, wie befreit man eine QByteArray erstellt auf diese Weise?

Konzeptionell - ich denke, würde free() auf den Zeiger über data() oder constData() anrufen, aber ich bin wirklich nicht sicher, ... hier ist ein Codebeispiel veranschaulicht den Anwendungsfall:

void doTest() { 
    QByteArray qba = partOne(); 
    partTwo(qba); 
    finished(qba); 
} 

QByteArray partOne() { 

    char *dataPtr = (char *)malloc(64); 
    //do some stuff to dataPtr 

    QByteArray qba = QByteArray::fromRawData(dataPtr, 64); 
    //do some stuff to qba 
    return qba; 
} 

void partTwo(QByteArray qba) { 
    //do more stuff to qba 
} 

void finished(QByteArray qba) { 
    //this? 
    free((void *)qba.constData()); 
} 
+0

Die sehr prominentes Beispiel beginnt mit 'static const char mydata [] = {'. Wie würdest du das * befreien? –

+0

Diese Frage ist mangelhaft ohne eine klare Aussage, warum Sie den Speicher zunächst über 'malloc' zuweisen. In C++ Code wäre es ein Antipattern. Sie kennen die 'QByteArray :: data()' Methode als eine Möglichkeit, mit Code zu interagieren, der einen rohen Zeiger benötigt, richtig? –

+0

Betrachten wir einen Fall, in dem wir den Speicher nicht zuweisen, sondern stattdessen einen Zeiger auf zugewiesenen Speicher von einer Bibliothek erhalten und diese Daten als QByteArray an einen anderen übergeben müssen - vorzugsweise ohne zu kopieren. – davidkomer

Antwort

3

wie funktioniert ein kostenloses ein QByteArray auf diese Weise erstellt?

Es ist einfach - man nicht. Das Byte-Array übernimmt nicht die Daten, also "befreien" Sie es nicht vom Byte-Array.

Wenn es notwendig ist, die Daten freizugeben, sollte diese Verantwortung auf den Code fallen, der die Daten zugewiesen hat. Nachdem Sie mit dem Byte-Array fertig sind, gibt es keine weiteren Verweise darauf.

Die Daten sind möglicherweise nicht frei verfügbar, daher sollten Sie nicht versuchen, sie aus dem Bytearray zu entfernen. Welcher Mechanismus den Daten zugeordnet wird, sollte seine Aufhebung der Zuordnung behandeln.

memory allocation 
    byte array construction 
     byte array usage 
    byte array destruciton 
memory deallocation 

Edit: Beachten Sie, dass mit COW es einen großen Unterschied zwischen „Sachen tun, um“ und „mach was mit“, wie er in Sie lesen oder schreiben, weil der Moment, den Sie schreiben, KUH-Kicks, die Die zugrunde liegenden Daten werden kopiert, und die Änderungen werden auf die Daten und nicht auf die Originaldaten angewendet. Dies geschieht natürlich nur dann, wenn mehr als ein Byte Array-Instanzen die Daten implizit gemeinsam nutzen, wie dies beispielsweise in partTwo() der Fall wäre. Wenn Sie nicht möchten, dass dies geschieht, gehen Sie lieber nach Referenz als nach Kopie. Offensichtlich, wenn COW eintritt, wäre es ein Problem, wenn Sie den Speicher von data() freigeben, weil Sie den neuen Speicher freigeben, der vom Bytearray zugewiesen wurde, und Ihre ursprüngliche Zuordnung würde in ein Speicherleck umwandeln. Die folgende Lösung sieht diese Möglichkeit vor.

void doTest() { 
    char *dataPtr = (char *)malloc(64); 
    //do some stuff to dataPtr 
    { 
     QByteArray qba = partOne(dataPtr); 
     partTwo(qba); 
    } // qba dies here 
    free(dataPtr); 
} 

QByteArray partOne(char *dataPtr) { 
    QByteArray qba = QByteArray::fromRawData(dataPtr, 64); 
    //do some stuff to qba 
    return qba; 
} 

void partTwo(QByteArray qba) { 
    //do more stuff to qba 
} 
+0

Nehmen wir an, dass die Schritte 1-3 (Speicherzuweisung -> Konstruktion -> einige Verwendung) in einer Funktion stattfinden, und der Rest der Schritte an anderer Stelle (mehr Verwendung -> Zerstörung -> Aufhebung der Zuordnung). In diesem Sinne, wie sollte diese "anderswo" Funktion mit Deallokation umgehen? – davidkomer

+0

Vielleicht war es nicht zu illustrativ zu sagen "der Code, der zugewiesen", mehr die konzeptionelle Programmeinheit. Wenn Sie das Byte-Array nicht an andere Stellen übergeben, wird es "absterben", da es am Ende dieser einen Funktion den Gültigkeitsbereich verlässt, so dass Sie die Daten kurz vor dem Zurückgeben der Funktion freigeben können. Dies würde sich theoretisch umkehren die letzten zwei Schritte, aber es wird ok sein, solange niemand das Array mehr benutzt. Oder Sie können einen intelligenten Zeiger verwenden, um den Speicher automatisch zu verwalten. Dann können Sie die oben beschriebene Reihenfolge verwenden. – dtech

+0

Wenn Sie zusätzliche Informationen veröffentlichen, was genau Sie mit dem Byte-Array tun, kann ich genauer sein. – dtech

0

fromRawData nimmt nicht das Eigentum, so die Daten, die Sie freigeben müssen besitzt Speicher sollte von Objekt freigegeben werden.

Konzeptionell - ich würde vermuten, free() auf den Zeiger über .data() oder .constData() aufgerufen wird, aber ich bin mir nicht sicher ...

, wie Sie es falsch ist kann nicht garantieren, dass QByteArray die Daten nicht besitzt. Z.B. wenn Sie den Inhalt der QByteArray die tiefe Kopie wird erstellt ändern und diese Kopie wird von QByteArray destructor befreit werden:

Ein weiterer Versuch, den Inhalt des zurück QByteArray oder einer Kopie aus, ihn zu ändern wird es dazu führen, Erstellen Sie eine tiefe Kopie des Datenarrays, bevor Sie die Änderung vornehmen. Dies stellt sicher, dass das Rohdatenfeld selbst niemals von QByteArray geändert wird.

1

Es gibt keine Notwendigkeit für Sie den Speicher manuell überhaupt zu verwalten:

auf dieser Seite
QByteArray partOne() { 
    QByteArray qba(64, Qt::Uninitialized); 
    auto dataPtr = qba(); 
    // use dataPtr 
    // do some stuff to qba 
    return qba; 
} 
Verwandte Themen