Forum: PC-Programmierung 64 Bit Pointer auf ungerade Speicherzelle - Datatype misalignment.


von Josef (Gast)


Lesenswert?

Hallo zusammen,

es ist kein GCC aber vll kennt trotzdem jemand  das Problem und eine 
elegante Lösung.

Ich arbeite Momentan mit Windows CE und nutze Visual Studio zur 
Programmierung.

Ich habe nun ein Array mit char Pointern auf einzelene Adressen. Die 
Adressen sind manchmal auch ungerade.
Wenn ich nun mit einem 64Bit Pointer auf die Adresse zugreifen möchte 
gibt es eine Fehlermeldung "Datatype misalignment."

Kennt jemand ein eleganten weg wie ich das verhinden kann? Wie schaffe 
ich es mit einem Pointer vom Datentyp unsigned long int auf einen 
unsigned char an einer ungeraden speicherzelle zuzgreifen?

Gruß
Josef

: Verschoben durch Moderator
von g457 (Gast)


Lesenswert?

> Kennt jemand ein eleganten weg wie ich das verhinden kann?

Die richtigen(tm) Datentypen nehmen.

> Wie schaffe ich es [..] auf einen unsigned char [..] zuzgreifen?
                              ^^^^^^^^^^^^^^^^^^^

Indem Du einen unsigned char* nimmst. Das war jetzt einfach.

HTH

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Alle vier oder acht Bytes einzeln lesen und dann per << und | zur
gewünschten Zahl zusammenbasteln.

von (prx) A. K. (prx)


Lesenswert?

Wäre das nicht in "PC Programmierung" passender?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

A. K. schrieb:
> Wäre das nicht in "PC Programmierung" passender?

Ja, stimmt.  Hab' ich verschoben.

von Josef (Gast)


Lesenswert?

Besten dank fürs verschieben!

Also das ganze sieht wie folgt aus. Der unsigned char pointer zeigt auf 
verschiedene Daten, manchmal Bytes, manchmal Float Werte oder 
irgendetwas anderes.

Später weiß ich aber wieviel Bits ich dem "objekt" mitteilen möchte, 
dies können 0-64 Bits sein. Also habe ich dort eine 64 Bit Variable mit 
Daten, wovon dann immer nur ein paar Bits Maskiert werden und in die 
Variable an der Pointeradresse des unsigned char pointer geschrieben 
werden.
Damit ich der Adresse die 64Bit Variable übergeben kann muss ich den 
Pointer doch als (unsigned long int *) casten.
also einfach einen unsigned char * zu nehmen ist nicht so einfach.
die Variante mit byte für byte ist auch nicht so einfach, bzw. deutlich 
rechen intensiever

von g457 (Gast)


Lesenswert?

Ah, Du willst also nicht auf einzelne unsigned char zugreifen (so wie 
Dus oben beschrieben hast) sondern auf Größeres in einem Block. Da hast 
Du im wesentlichen die folgenden Optionen:
- eine Hardwarearchtiektur nehmen, der mit non-aligned-Zugriffen 
zurechtkommt
- einen Compiler nehmen, der automagisch den nötigen Code für 
non-aligned-Zugriffe aussenrum strickt
- den Speicher adäquat ausrichten (entweder beim Anfordern des Puffers 
oder ggf. in einen Passenden umkopieren)
- die chars selber zu Fuß zusammenverheiraten

Die ersten beiden fallen vermutlich flach, Nummer 3 geht nur dann 
effizient wenn die größeren Datentypen immer an der 'gleichen' 
(relativen) Stelle liegen. Nummer 4 geht immer ist aber u.U. 
ineffizient.

HTH

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Josef schrieb:
> die Variante mit byte für byte ist auch nicht so einfach, bzw. deutlich
> rechen intensiever

Nein, ist sie nicht.  Sie macht dir nur deutlich, was andere
Prozessoren dir verstecken; die Arbeit selbst haben sie damit aber
so oder so.

Daher entwirft man vernünftige Datenprotokolle auch so, dass alle
darin enthaltenen Datenfelder mit ihrer "natürlichen Ausrichtung"
arbeiten können (also 16-bit-Werte auf durch 2 teilbaren Adressen,
32-bit-Werte auf durch 4 teilbaren usw.).  Ein Weg, wie man das
erreicht ist, dass man die längsten Datentypen zuerst anordnet, und
von da immer kürzer wird.  Ggf. muss halt mal ein Füllbyte eingefügt
werden, wenn's nicht anders geht.

Wenn du dich mal bei den Internet-Protokollen umsiehst, wirst du diese
Vorgehensweise dort sehr häufig finden.  Wenn du dich im PC- und
Microsoftbereich umsiehst, wirst du sie dort selten finden ... kost'
ja nix, macht ja der Prozessor. :-/

von Josef (Gast)


Lesenswert?

Ja eventuell kam es beim ersten Post nicht ganz rüber, aber genau wie du 
es nun gesagt hast möchte ich auf mehrere in einem block zugreifen, bzw. 
manchmal nur einen und manchmal mehrere.

lösung 1 fällt raus ;)
lösung 2 kenne ich keinen
lösung 3 fällt wohl auch raus weil es einfach ein speicherblock ist, wo 
noch mehrere systeme später drauf zugreifen und dort sollen die daten 
alle hintereinander liegen.
lösung 4 wird schwer, da manchmal nicht nur an bit 0 des bytes 
angefangen wird sondern auch an anderen bits in dem byte. aber wenn es 
keine bessere lösung gibt, dann muss ich da wohl durch ...

von (prx) A. K. (prx)


Lesenswert?

Jörg Wunsch schrieb:

> Wenn du dich mal bei den Internet-Protokollen umsiehst, wirst du diese
> Vorgehensweise dort sehr häufig finden.

Nja... Du kriegt entweder den Ethernet-Frame aligned, oder den IP 
Header, aber nicht beide. Um das in diesem Zusammenhang wichtigere IP zu 
alignen muss man also den Frame-Puffer gezielt misalignen.

Zu allem Überfluss haben die meisten real verwendeten Architekturen die 
exakt umgekehrte Bytereihenfolge als im Netz üblich. Soviel zu Thema 
"geschickte Planung".

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

A. K. schrieb:
> Zu allem Überfluss haben die meisten real verwendeten Architekturen die
> exakt umgekehrte Bytereihenfolge als im Netz üblich.

Allerdings sind diese erst weit nach dem Entwurf dieser Protokolle
in die Klasse "die meisten" aufgestiegen. ;-)  Zu Zeiten, da diese
Protokolle entworfen worden sind, war das keineswegs der Fall, da
dürfte die Vax so ziemlich die Ausnahme gewesen sein.

von bluppdidupp (Gast)


Lesenswert?


von bluppdidupp (Gast)


Lesenswert?

(ok scheint wohl nur für x64 und itanium zu gelten)

von (prx) A. K. (prx)


Lesenswert?

bluppdidupp schrieb:

> (ok scheint wohl nur für x64 und itanium zu gelten)

x86 benötigt es nicht. Aber in WinCE gibts ja noch mehr Plattformen.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.