Problem mit memcpy und struct



  • Hallo zusammen,

    ich hab ein Problem bei der Benutzung von memcpy im Zusammenhang mit structs.
    Ich programmiere mit C++ im Rahmen eines Qt Projekts.
    Nach einem kurzen Blick in das Linux/Unix Forum und der Feststellung, dass die Beiträge
    dort eher von der Natur "Hilfe mein X Server geht nicht mehr" sind dachte ich mir, dass ich
    hier vielleicht eher Hilfe bekommen kann 😉

    Um dieses struct handelt es sich (IconView_Type ist vom Typ int)

    struct IconViewTypeAndText
        {
            IconView_Type type;
            QString text;
        };
    

    Wird kodiert (im Rahmen von drag 'n drop) mit...

    QByteArray array;
    IconViewTypeAndText * pData = new IconViewTypeAndText;
    pData->type = item->itemType();
    pData->text = item->text();
    
    array.resize( sizeof( pData ) );
    memcpy( array.data(), pData, sizeof( pData ) );
    setEncodedData( array );
    

    ... und dekodiert mit

    QByteArray payload = mimeSource->encodedData();
    IconViewTypeAndText * pData = new IconViewTypeAndText;
    memcpy( pData, payload.data(), sizeof( payload.data() ) );
    

    Problem dabei ist jetzt, dass ich zwar auf pData->type zugreifen kann,
    pData->text allerdings leer ist.
    Woran könnte das liegen? Dass text ein QString ist vielleicht?

    UPDATE:
    Bei anderer Reihenfolge im struct kann ich nun auf text
    zugreifen, type ist dann immer NULL.
    D.h. handelt sich entweder um ein size Problem oder ich hab bei der
    Zuweisung irgendwo noch einen Fehler...

    LOESUNG:
    Array Größe war das Problem.
    Mit sizeof(pData)*2 und sizeof(payload.data())*2 gehts 😉

    Danke und Gruß,
    andyknownasabu



  • Was ich auf den ersten Blick um die Uhrzeit sehe :
    memcpy( array.data(), pData, sizeof( pData ) ); ???

    muesste das ned sizof(IconViewTypeAndText) heissen ?
    Pdata ist nur der pointer, und duerfte damit immer 4 byte gross sein ?

    ne andere sache: QString text; mittels memcpy kopieren ist sehr mutig 😃
    memcpy auf wrapper kann die schoensten effekte erzeugen ... weisst du, was Qstring so alles mit seinem internen Zeiger so macht .... von denen solltest ne tiefe kopie machen .... und ned nur den zeiger ins byteArray ablegen ...
    Hat Qstring ned ne moeglichkeit, sich in nem stream zu serializen, vielleicht solltest das nutzen ....

    Ciao ...



  • RHBaum schrieb:

    Was ich auf den ersten Blick um die Uhrzeit sehe :
    memcpy( array.data(), pData, sizeof( pData ) ); ???

    muesste das ned sizof(IconViewTypeAndText) heissen ?
    Pdata ist nur der pointer, und duerfte damit immer 4 byte gross sein ?

    Jup, danke! Das war in der Tat genau das Problem (siehe meinen Beitrag).
    Da hatte ich deinen allerdings noch gar nicht gelesen, jetzt hab
    ichs also nochmal von xxx*2 auf deines geändert. Passt auch 😉

    RHBaum schrieb:

    ne andere sache: QString text; mittels memcpy kopieren ist sehr mutig 😃
    memcpy auf wrapper kann die schoensten effekte erzeugen ... weisst du, was Qstring so alles mit seinem internen Zeiger so macht .... von denen solltest ne tiefe kopie machen .... und ned nur den zeiger ins byteArray ablegen ...
    Hat Qstring ned ne moeglichkeit, sich in nem stream zu serializen, vielleicht solltest das nutzen ....

    Mutig bin ich zwar, aber dann doch nicht _so_ 😉
    Ne tiefe Kopie mach ich, hab ich nur nicht mehr extra dazugeschrieben...

    Danke für die Hilfe zu solch später Stunde!



  • ok, nun den ersten Kaffee hinter mir, nun bin ich auch streitlustiger 😃

    Sieht halt nur doof aus, QByteArray QString ... usw und memcpy im selben modul zu verwenden, den OOP Freaks wuerde der Kaffee nun nich mehr schmecken 🙂

    Warum ned nen Wrapper fuer dein IconViewTypeAndText schreiben, und den ne Passende methode spendendieren, die Dir deine daten im ByteArray serialisiert.

    Zumal ich ned ganz verstehe, wie du das teil wirklich ablegst. mit dem Memcopy kopierst du die rohdaten(den zeiger auf die zeichenkette) des QStrings ins Bytearray ... wo kopierst du die eigentliche zeichenkette hin, und beim auslesen, wie baust du das zusammen ? der zeiger nuetzt dir eigentlich gar nix ?

    Ciao ...



  • RHBaum schrieb:

    Sieht halt nur doof aus, QByteArray QString ... usw und memcpy im selben modul zu verwenden, den OOP Freaks wuerde der Kaffee nun nich mehr schmecken 🙂

    Warum das? Ich verwende es in einer abgeleiteten Klasse von QDragObject...

    Warum ned nen Wrapper fuer dein IconViewTypeAndText schreiben, und den ne Passende methode spendendieren, die Dir deine daten im ByteArray serialisiert.

    Das würde sicher auch gehen, ich versteh allerdings noch nicht so recht den Vorteil oder warum das dann sauberer wäre als meine jetzige, funktionierende Methode... mal ganz abgesehen davon, das Serialisieren dann zu implementieren... 😉

    Zumal ich ned ganz verstehe, wie du das teil wirklich ablegst. mit dem Memcopy kopierst du die rohdaten(den zeiger auf die zeichenkette) des QStrings ins Bytearray ... wo kopierst du die eigentliche zeichenkette hin, und beim auslesen, wie baust du das zusammen ? der zeiger nuetzt dir eigentlich gar nix ?

    Hm, ich muss zunächst sagen, dass ich in der Tat nicht genau weiß, ob und wie QString intern mit Zeigern hantiert.
    Jedenfalls hab ich Beispielcode im Netz gefunden, es mit meinem struct genauso versucht und es funktioniert 😉

    Folgendermaßen:
    Bei "startDrag()" wird ein neues "OwnDragObject" erzeugt, das intern eben
    diese beiden Daten - type<int> und text<QString> - des aktuell markierten "OwnIconViewItems" mit einer tiefen Kopie in ein QByteArray kopiert (memcpy).
    Beim "contentsDropEvent" wird dann eine Methode der Klasse "OwnDragObject" aufgerufen, die diese Daten mittels memcpy wieder genauso in ein
    IconViewTypeAndText zurückkopiert.
    Zugreifen kann ich dann bequem mittels IconViewTypeAndText->[type|text]

    Für Drag 'n Drop hab ich im Netz ausser dem einen memcpy Beispiel nichts Weiteres gefunden.
    Wenn es eine andere, "üblichere" Methode gibt beliebige Daten auf diese Weise zu übergeben würd mich das sehr interessieren... Nur raus damit 😉



  • SPiel mal bisserl mit sizeof und Qstring rum, muesstest feststellen, das QString immer gleichgross bleibt, unabhaengig von der Zeichenkette die es verwaltet. Sicheres indiz dazu, das QString den speicher fuer die zeichenkette aufn dynamisch anlegt. Sprich du bekommst es nicht mit einem memcpy gebacken.

    Was du brauchst, ist nen speicherblock wo alle "daten" am Stueck vorliegen ...

    Moeglichkeiten
    1.
    Qstring gibt dir irgendwie nen zeiger auf die zeichenkette. Mit viel Glueck ist das kein Unicode, also kannst die daten mittels strlen/strcpy(alternativ memcpy) in dein Bytearray schieben, ansonsten wirds ein bisserl haariger. So kriegst es wenigstens zum funktionieren. Die OOP freaks sind aber immer noch ned gluecklich. memcpy/ strcpy solltest wirklich nur auf Array of PODs anwenden, und das auch ganz tief versteckt in privaten methoden.

    Du hasst hier voll nen allgemeines Problem. Braucht man ned nur per drag and drop, sondern bei allen moeglichen geschichten ( Moniker allgemein (CORBA z.b.) Netzwerk (Chatclients ... etc), Serialisierung ist nur nen kleiner teil. Die loesung Sind hier Datenstroeme. Und da das jeder braucht, gibts auch hilfe zu.
    Schau dir mal QDataStream an ... da kannst deinen QString ganz locker unterbringen. vielleicht hast glueck, und dein Drag und Drop besteht ned so zwingend auf nen QByteArray ... sondern kann auch mit QDataStream arbeiten, dann wirds ganz einfach ... ansonsten musst noch QByteArray mit QDatastream verheiraten, was dir leider aber sicher noch ne zusaetzliche kopie einbringt. Und nen kurzer blick in die QT doku zeigt, das QByteArray und QDatastream sich ned ganz fremd sind, was die Hochzeit wesentlich vereinfachen duerft!
    Hier werden dann auch dien OOPler gluecklich ... irgendwann 😃

    Vielleicht zeigst mal bisserl mehr code, dann kann ich auch genauer werden.

    Ciao ...
    P.S.
    Nicht alles was man liest ist Gut ! Aber mit ein bisserl uebung kann mans irgendwann mal besser :p

    Für Drag 'n Drop hab ich im Netz ausser dem einen memcpy Beispiel nichts Weiteres gefunden.

    Gib mal den Link, dann steinigen und federn wir den Author :p


Anmelden zum Antworten