Verständnisproblem beim konvertieren von struct -> QByteArray -> struct
-
Ich habe die folgende Struktur, wo ich ein dynamisches char-array benutze.
struct test{ int value_a; unsigned short value_b; char *c; };Ich erzeuge eine Instanz von der Struktur, allokiere Speicher für das c-Array und befülle es.
test *ptr = new test; //die neue instanz ptr->value_a = 5; //befülle die struktur ptr->value_b = 12; ptr->c = new char[2 * sizeof(char)]; //allokiere speicher für 2bytes ptr->c[0] = 'A'; ptr->c[1] = 'B'; //ende char *p = (char*)ptr; //caste hier ptr auf char* für den Ctor von QByteArray QByteArray bytearray(p, 4 + 2 + 2 * sizeof(char)); // 4bytes (integer) + 2bytes (unsigned short) + 2bytes (char array mit 'A' und 'B') test *xy = (test*)bytearray.data(); // nun hole ich mir die Daten aus dem QByteArray zurück int p = xy->a; unsigned short q = xy->b; char r[2]; memcpy(&r,xy->c,2); // kopiere das array mit 'A' and 'B' in r[2]Wenn ich nun versuche auf xy->c (das array) zuzugreifen, erhalte ich einen ungültigen Pointer.
Dadurch schlägt auch memcpy fehl.Nun kommt das, was mich total verwirrt.
ptr->c = new char[3 * sizeof(char)]; ptr->c[0] = 'A'; ptr->c[1] = 'B'; ptr->c[2] = 'C';Erhöhe ich die Array-Größe auf 3-Elemente, funktioniert das ganze.
Natürlich ändere ich dabei alle anderen Stellen wie
"2 * sizeof(char)" zu "3 * sizeof(char)" usw...Was ist hier los? warum gehts mit 3 und nicht mit 2?
-
Ich glaub ich habs...
QByteArray hat keine tiefe kopie gemacht!
Es hat jedesmal meinen pointer kopiert.Weiss jemand was ich ändern muss um nicht den pointer zu kopiere sondern wirklich den Inhalt des arrays in meiner struktur.
-
Mal ganz ehrlich: Was du da tust kann man bestenfalls als grauenvoll bezeichnen.
- Du castest wild hin und her. Mal abgesehen davon dass es sich dabei um C-Casts handelt und das was du da tust eigentlich ein reinterpret_cast ist, verlierst du damit mutwillig jede Typsicherheit.
- Du erzählst dem QByteArray, dass es auf einen 8 Byte großen Bereich zeigt. tatsächlich sinds aber 10 oder 12 Byte, je nach Alignment. Dein Fehler dabei ist, dass du 2 Byte für das dynamisch allokierte char-Array angibst statt der 4 byte für den char-Pointer.
- Du hast es fertig gebracht, überall feste Zahlen einzucodieren, nur beim char benutzt du sizeof(). Glückwunsch, char ist der einzige Datentyp für den die Größe im Standard festgelegt ist. das sizeof(char) ist also überflüssig (nämlich per Definition immer 1), die Annahme, dass ints immer 4 Byte groß sind un short immer 2 Byte, ist aber eben nur eine Annahme.
- Du sagst was von nicht tief kopiert - da wird auch nichts tief Kopiert. QByteArray ist dazu da, um char's zu kopieren/verwalten, nicht irgendwelche structs. Dein QByteArray interpretiert also die ersten 8 Byte deines struct um, und interpretiert diese als char's.
Schau dir am besten nochmal ein paar C++-Grundlagen an und verstehe was da passiert, bevor du dich mit Qt, C-Casts und anderen Dingen verlustierst. Zu wissen, was du mit deinen Anweisungen aussagst ist wichtiger, als sie einfach hinzuschreiben und zu gucken was passiert.
-
bei new reicht folgendes
typ * var = new typ[n]; // statt n-mal sizeof(typ)würdest du das so mit z.b. int machen, oder einer eigenen geschriebenen klasse hättest du auf einmal statt deinen 5 gewollten elementen speicher für 20 oder mehr geholt
-
Erstmals danke für die reichlichen Antworten.
Die oberen Codeschnipsel gehören nicht zu meinem eigentlichen Code.
Das sollte nur zur Demonstration dienen. Aus diesem Grund, dieser etwas schmutzige Code und die C-casts.Bit-alignment ist kein Problem, da ich hierbei "pragma pack(1)" verwende
um keine Stopf-Bits zu bekommen.
Den Fehler mit den 2Bytes für den Pointer habe ich zuvor bemerkt, siehe vorheriges Post von mir.
Das Problem dabei war, ich bin davon ausgegangen, dass QByteArray den Inhalt und nicht den Pointer kopier. (Inhalt = 2Bytes, Pointer 4 Bytes)Siehe 1. Das ist nur ein fast&dirty Code zur Demonstration des Problems.
Ja das stimmt wohl. Habe ehrlich gesagt nicht daran gedacht oder besser gesagt nicht gewusst, dass QByteArray einfach nur die struktur "um-interpretiert" wird.
Ich sollte eventuell mal sagen was dahinter steckt:
Diese Struktur enthält Daten, die vom Benutzer der Anwendung kommen und über die serielle Leitung geschickt werden sollen.
Da die Eingabe vom Benutzer unterschiedlich lang sein kann, muss ein char-array her, welches diese unterschiedlich langen Daten unterbringen kann.Wie wird denn sowas generell gemacht? Man kann doch keine fest-definierten Arrays nehmen.