eigene Methode zur Objektkopie?



  • Um, was genau macht diese Bibliothek, dass da einfach so ein realloc() passieren kann? Wie willst du diese Deep-Copy genau anstellen, wenn du nichtmal weißt, was das eigentlich für eine Struktur ist, auf die dein Member zeigt?



  • dot schrieb:

    Um, was genau macht diese Bibliothek, dass da einfach so ein realloc() passieren kann? Wie willst du diese Deep-Copy genau anstellen, wenn du nichtmal weißt, was das eigentlich für eine Struktur ist, auf die dein Member zeigt?

    Es ist eine ASN.1-Bibliothek (asn1c). Die Struktur wird zuerst mit dem asn1c-Compiler generiert. Dieser erzeugt dann C-Code, welcher dann anschließend für die Implementierung genutzt wird. Die Inhalte der Struktur wird vor der Implementierung mit der ASN.1-Syntax definiert und daher ist mir auch der Aufbau der Struktur bekannt (etwas anderes hatte ich doch nicht behauptet). Der Zugriff und das Freigeben der einzelnen Elemente erfolgt über die Funktionsaufrufe der Bibliothek. Ich denke mal, dass der Inhalt in der Tiefe nicht so relevant ist.

    Sollte es so viel Verwirrung schaffen, dann nehmen wir vereinfacht folgendes an:

    typedef struct MyDeepStructure
    {
    	unsigned char *buf;
    	int size;
    } MyDeepStructure_t;
    

    ...und die Methode 'copy()' kopier die enthaltenen Daten 1:1 (alloziert für die Kopie neuen Speicher, kopiert den Inhalt von '*buf' und die Größe 'size')



  • Nun, da ist mir aber weiterhin unklar, wo genau hier das struct selbst per realloc() modifiziert werden muss...



  • SBond schrieb:

    Die Speicherverwaltung erfolgt mit calloc/free, da die externe Bibliothek die ich verwende auch damit arbeitet und ggf. ein realloc auf die Membervariable 'mp_myStructure' anwendet.

    oh nein. Mein Fehler, sorry 😞

    Da habe ich es falsch formuliert. Das realloc wird auf die Elemente innerhalb der Membervariable 'mp_myStructure' anwendet und nicht auf die Membervariable selbst. 'mp_myStructure' wird allerdings durch eine Bibliotheksfunkton (mittels free()) freigegeben. Daher kommt kein new/delete zum Einsatz.

    Sorry, dass ich hier was vertauscht habe.



  • Bin immer noch etwas verwirrt: Wird mp_myStructure jetzt direkt per calloc()/free() erzeugt und freigegeben oder rufst du dazu irgendwelche Funktionen dieser Bibliothek auf, die lediglich intern calloc()/free() verwenden?



  • Meiner Meinung nach, macht Deine copy-Funktion genau dass, was operator= machen sollte:

    class MyClass : protected MyWrapper // MyWrapper besitzt selbst keine Membervariablen und stellt nur Methoden bereit 
    { 
    public: 
        MyClass() : 
            mp_myStructure ( static_cast< MyDeepStructure_t* >( calloc(1, sizeof(MyDeepStructure_t))))
        { 
        } 
    
        virtual ~MyClass() 
        { 
            // gibt den dynamischen Speicher rekursiv frei (inklusive 'mp_myStructure' selbst) 
            freeStructure(mp_myStructure); 
        } 
    
        MyClass(const MyClass &other) : 
            mp_myStructure ( static_cast< MyDeepStructure_t* >( calloc(1, sizeof(MyDeepStructure_t))))
        { 
            *this = other;
        } 
    
        MyClass &operator=(const MyClass &other) 
        { 
            // kopiert die Inhalte von 'other.mp_myStructure->...' nach 'this->mp_myStructure->...' 
    
            return *this; 
        } 
    
        // ...weitere Klassenmethoden... 
    
    private: 
        // Membervariablen (nur eine) 
        MyDeepStructure_t *mp_myStructure; 
    };
    

    was aber eleganter wäre, wäre copy&swap:

    class MyClass : protected MyWrapper // MyWrapper besitzt selbst keine Membervariablen und stellt nur Methoden bereit 
    { 
    public: 
        MyClass() : 
            mp_myStructure ( static_cast< MyDeepStructure_t* >( calloc(1, sizeof(MyDeepStructure_t))))
        { 
        } 
    
        virtual ~MyClass() 
        { 
            // gibt den dynamischen Speicher rekursiv frei (inklusive 'mp_myStructure' selbst) 
            freeStructure(mp_myStructure); 
        } 
    
        MyClass(const MyClass &other) : 
            mp_myStructure ( static_cast< MyDeepStructure_t* >( calloc(1, sizeof(MyDeepStructure_t))))
        { 
            // kopiert die Inhalte von 'other.mp_myStructure->...' nach 'this->mp_myStructure->...' 
        } 
    
        MyClass &operator=(MyClass other) 
        { 
            swap( other );
            return *this; 
        } 
    
        void swap( MyClass& other )
        {
            std::swap( mp_myStructure, other.mp_myStructure );
        }    
    
    private: 
        // Membervariablen (nur eine) 
        MyDeepStructure_t *mp_myStructure; 
    };
    

    HTH



  • dot schrieb:

    Bin immer noch etwas verwirrt: Wird mp_myStructure jetzt direkt per calloc()/free() erzeugt und freigegeben oder rufst du dazu irgendwelche Funktionen dieser Bibliothek auf, die lediglich intern calloc()/free() verwenden?

    Ja das ist in der Tat etwas verwirrend. Die Membervariable 'mp_myStructure' muss ich selber mit calloc() allozieren und initialisieren. Die Freigabe erfolgt allerdings über eine Bibliotheksfunktion. Die Bibliothek gibt dabei auch alle enthaltenen Elemente frei und das spart mir viel arbeit.

    @Torsten: auch dir vielen Dank für die Unterstützung 🙂
    Funktioniert prima.

    Könnte man das nicht auch gleich so machen?:

    MyClass &operator=(MyClass other) 
        { 
            std::swap( mp_myStructure, other.mp_myStructure );
            return *this; 
        }
    

    Bzw. bringt es einen bestimmten Vorteil, swap() als Funktion auszulagern?

    viele Grüße,
    SBond



  • SBond schrieb:

    dot schrieb:

    Bin immer noch etwas verwirrt: Wird mp_myStructure jetzt direkt per calloc()/free() erzeugt und freigegeben oder rufst du dazu irgendwelche Funktionen dieser Bibliothek auf, die lediglich intern calloc()/free() verwenden?

    Ja das ist in der Tat etwas verwirrend. Die Membervariable 'mp_myStructure' muss ich selber mit calloc() allozieren und initialisieren. Die Freigabe erfolgt allerdings über eine Bibliotheksfunktion. Die Bibliothek gibt dabei auch alle enthaltenen Elemente frei und das spart mir viel arbeit.

    Nur mal so aus Interesse: Was ist denn das bitte für eine Bibliothek?



  • dot schrieb:

    Nur mal so aus Interesse: Was ist denn das bitte für eine Bibliothek?

    Ein ASN.1-Compiler für C

    http://lionet.info/asn1c/blog/ 😉

    Wurde so wie es aussieht von einer einzelnen Person implementiert. Ist von der Dokumentation und Verwendung her etwas gewöhnungsbedürftig, aber ich bin froh dass ich es nutzen kann 😃



  • SBond schrieb:

    Könnte man das nicht auch gleich so machen?:

    Ja, könnte man so machen. Wenn Du die swap() hast, dann kann sie aber auch von anderen genutzt werden. Du kannst auch std::swap() für deinen Typen überladen, und dann würden davon auch algorithmen profitieren, die intern swap() verwenden.



  • ok. vielen Dank 😃


Anmelden zum Antworten