Bytearray auf Structarray casten.
-
Hi!
um ein Bytearray auf einen Struct zu casten muss man ja nur folgendes machen:
StructXYZ* bla = (StructXYZ*)bytearray; //Wenn bytearray ein char* ist.Aber wie caste ich ein Bytearray auf ein array von structs variabler größe?
Ich habs so versucht, aber es funktioniert nicht.int size = sSDB.getDataSize() / (sizeof(StructXYZ)); //size ist für die Schleife die dann data[i].whatever bedient. StructXYZ** data = (StructXYZ**)bytearray;jemand eine Idee?
-
Ob einzelne Struktur oder Array aus Strukturen macht keinen Unterschied, da das Array zu einem Zeiger zerfällt. Dank Zeigerarithmetik kannst du das so handhaben:
int main() { unsigned int Count = sSDB.getDataSize() / sizeof( StructXYZ); StructXYZ* ptr = reinterpret_cast<StructXYZ*> bytearray; // ++ptr verschiebt den Zeiger auf den nächsten Eintrag for( unsigned int i = 0; i < Counter; ++i, ++ptr ) { // tu was mit ptr } }
-
cl90 schrieb:
um ein Bytearray auf einen Struct zu casten muss man ja nur folgendes machen:
StructXYZ* bla = (StructXYZ*)bytearray; //Wenn bytearray ein char* ist.Wenn das Alignment von bytearray nicht stimmt, kann dir das aber auch einfach abschmieren.
-
Ob Array oder nicht, macht keinen Unterschied. StructXYZ[10] steht für 10 hintereinander im Speicher liegende StructXYZ-Objekte statt nur eins.
StructXYZ* bla = (StructXYZ*)bytearray; //Wenn bytearray ein char* ist....klappt solange
bytearraywirklich auf etwas zeigt, was man als hintereinander liegende StructXYZ-Objekte interpretieren darf.Allerdings musst Du da mit dem Alignment aufpassen, wenn Du so etwas machst.
Und ich würde diesen Cast auch deutlich als den kennzeichnen, der er ist. "(Typ)" kann nämlich alles mögliche sein ... von harmlosen statischen Casts bis hinzu "böseren" reinterpret- und const-Casts. In diesem Fall machst Du hier einen reinterpret_cast, was, wenn man das auch so ausschreibt, immerhin eine Warnung im Quellcode darstellt, dass hier etwas "schmutziges" passiert.
-
Um das mit dem Alignment zu garantieren, solltest du bei der Deklaration des
char-Arraysalignas(alignof(StructXYZ))-Attribut verwenden.
-
ok also um es "sicher" zu machen muss ich beim erstellen des chararrays dein Atribut benutzen?
das stellt dann sicher das das chararray was genau macht? Das es so groß ist wie die Struct? oder das die Daten zusammenhängend im Speicher liegen? (Letzteres dachte ich wäre immer gegeben bei einem array)DocShoe schrieb:
int main() { unsigned int Count = sSDB.getDataSize() / sizeof( StructXYZ); StructXYZ* ptr = reinterpret_cast<StructXYZ*> bytearray; // ++ptr verschiebt den Zeiger auf den nächsten Eintrag for( unsigned int i = 0; i < Counter; ++i, ++ptr ) { // tu was mit ptr } }Danke.
Schiebt der ptr jetzt um die größe eines Structs? also quasi prt[0] bis ptr[9] deckt alle structs des arrays ab?
-
(Letzteres dachte ich wäre immer gegeben bei einem array)
Korrekt, das ist immer gegeben.
Das es so groß ist wie die Struct?
Nein, wie groß es ist legen nur der Elementtyp und die Anzahl der Elemente fest.
Mein Attribut garantiert, dass das Array eine Ausrichtung hat, die kompatibel mit der des
StructXYZist. Du solltest mal die Links anklicken, die ich in meinem Post platziert habe. Oder dem von kkaw.Ich habe gerade auch zufällig im Standard nachgelesen, dass du das Attribut noch abkürzen kannst (§7.6.2/3):
alignas(StructXYZ). Die Deklaration des Arrays sollte demnach so aussehen:alignas(StructXYZ) char bytearray[sizeof(StructXYZ)]; // Hat genau Platz für ein StructXYZ; Du kannst mit einem Faktor die Anzahl variierenSo solltest du einen Zeiger
StructXYZ*auf dieses Array nutzen können, ohne Ausrichtungs-Probleme zu haben.Außerdem kannst du auch
std::array<char>verwenden: Auf das unterliegende Array greifst du mit der Memberfunktiondata()zu (das&arr[0]-Idiom ist nicht nötig). Und auf die Größe mitsize().