Hallo
Interessehalber eine Frage.
Für ein Compact Framework Projekt kopiere ich Daten zwischen Strukturen mit unsafe fixed Pointern.
Dabei habe ich bemerkt dass ich nur dann einen int wohin kopieren kann, wenn die Pointeradresse durch 4 teilbar ist.
Also
int* ptr = &array[0];
*ptr = 5; 0k
*(prt + 1) = 5; nicht ok
*(ptr + 4) = 5; wieder ok
Das Programm läuft einfach nicht mehr weiter. Im Debugger steigt der Code ab der Codezeile einfach aus, es gibt keinen Ausführungspunkt mehr und "Pause" bringt keine Reaktion. Ich muss alles abschießen.
In einer PC-Version funktioniert das ganze mit beliebigen Adressen.
Warum und wie Daten an solchen Adressen ausgerichtet werden ist mir klar. Die Lösung auch, ich kopiere einfach einzelne Bytes.
Nicht klar ist mir warum diese Reaktion kommt. Hängt es vom Prozessor ab ob er sowas macht oder nicht? Warum gibt es hier keine Exception?
Das Fachwort zu dem Verhalten heisst "Data structure alignment".
Deswegen mache ich bei unsafe Code oft Filler rein oder die Reihenfolge sieht so aus, dass zuerst Zahlen und dann die einzelnen Bytes kommen.
In dem verlinkten Artikel findest Du jede Menge Info dazu. Gibt auch den Fall, dass nicht aligned das Programm langsamer macht.
Mit sowas konnte man schon die PDP11 oder den 68000 abschießen.
Das Aligning kenne ich schon. Nur kann ich bei einem Array leider nicht anfangen zu alignen wenn die Daten am Stück sein sollen 😃
Ich behelfe mir jetzt mit einzelnen Bytes die ich kopiere.
Was mich wundert ist dass da einfach alles völlig abbricht. Mich hätte interessiert was da im Prozessor passiert.
Deswegen arbeitet man am besten mit Fillern/Padding. Im Zweifel ist das die saubere Lösung.
Manche Compiler machen das auch automatisch.
Du handelst Dir neben Abstürzen auch schnell Geschwindigkeitsprobleme ein.
Ist schon klar, aber wenn ich einen Datenstrom hab der nunmal dieses Format haben soll, kann ich da nicht einfach beliebig Bytes schieben 😉
Aus
int* ptr = &array[0];
würde ich schlussfolgern, dass
\*(prt + 1)
aufgrund der Pointer-Arithmetik auch an einer durch 4 teilbaren Adresse liegt. Zumindest, wenn ein int 4 Bytes groß ist und array an einer entsprechenden Adresse liegt.
Es muss also an etwas anderem liegen.
ja da hast du ehrlich gesagt recht 😃 Ich habe im Original einen byte* verwendet. Bei dem wird mit +1 tatsächlich zum nächsten Byte weiter geschaltet. Hab ich in meinem Beispiel übersehen.
Die Frage bezog sich jedenfalls wirklich auf einzelne Byte Adressen.