2016-06-15 2 views
1

Ich versuche, Embed Code in Windows-Plattform zu portieren. Ich bin unter Problem gestoßen Ich poste hier einen Beispielcode hier. hier, auch nachdem ich Int24 Größe bleibt 12 Bytes in Windows, warum?Warum Größe der Struktur ändert sich nicht, wenn 24 Bit Ganzzahl verwenden

struct INT24 
{ 
    INT32 data : 24; 
}; 

struct myStruct 
{ 
    INT32 a; 
    INT32 b; 
    INT24 c; 
}; 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    unsigned char myArr[11] = { 0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00, 0xFF,0xFF,0xFF }; 
    myStruct *p = (myStruct*)myArr; 
    cout << sizeof(*p); 
} 
+4

Denken Sie über 'myStruct [N]' und Ausrichtung nach. –

+2

'INT32 data: 24;' belegt immer noch 4 Bytes. –

+0

, aber ich zwinge es, 3 Bytes zu verwenden. – vivek

Antwort

3

Es gibt zwei Gründe, von denen jeder für sich genug wäre.

  • Vermutlich ist die Größe INT32 4 Bytes. Die Größe INT24 ist ebenfalls 4 Bytes, weil sie ein INT32 Bitfeld enthält. Da myStruct 3 Mitglieder der Größe enthält 4, also seine Größe mindestens sein muss, 12.
  • Vermutlich ist die Ausrichtungsanforderung von INT32 4. So ist, auch wenn die Größe von INT24 3, würde die Größe von myStruct noch müssen sein 12, weil es zumindest die Ausrichtung Anforderung von INT32 und damit die Größe von myStruct müssen gepolstert zum nächsten Vielfachen von 4.

eine Möglichkeit oder eine Umgehungs haben muss?

Dies ist implementierungsspezifisch, aber der folgende Hack kann für einige Compiler/CPU-Kombinationen funktionieren. Im Handbuch Ihres Compilers finden Sie die Syntax für ähnliche Funktionen und im Handbuch für Ihre Ziel-CPU, ob sie nicht-ausgerichteten Speicherzugriff unterstützt. Beachten Sie auch, dass ein nicht ausgerichteter Speicherzugriff eine Leistungseinbuße zur Folge hat.

#pragma pack(push, 1) 
struct INT24 
{ 
INT32 data : 24; 
}; 
#pragma pack(pop) 

#pragma pack(push, 1) 
struct myStruct 
{ 
INT32 a; 
INT32 b; 
INT24 c; 
}; 
#pragma pack(pop) 

Das Packen eines Bitfeldes funktioniert möglicherweise nicht in allen Compilern gleich. Überprüfen Sie, wie sich Ihr Verhalten verhält.

Ich denke, dass eine standardkonforme Art wäre, char-Arrays der Größen 3 und 4 zu speichern, und wann immer Sie eine der ganzen Zahlen lesen oder schreiben müssen, müssten Sie den Wert std::memcpy haben. Das wäre etwas mühsam zu implementieren und möglicherweise auch langsamer als der # Pragma Pack Hack.

+0

danke für die Antwort, aber leider funktioniert es nicht mit VS 2005, die ich verwende. – vivek

+0

@ Vivek oh gut, dann verwenden Char-Arrays. – user2079303

1

Leider für Sie, der Compiler den Code für eine bestimmte Architektur bei der Optimierung behält sich das Recht vor, Pad aus der Struktur durch Zwischenräume zwischen den Mitgliedern und auch am Ende der Struktur eingefügt wird.

Mit einem Bitfeld nicht die Größe der struct reduzieren; Sie erhalten immer noch den ganzen Typ "Fielded" in der struct.

Der Standard stellt sicher, dass die Adresse des ersten Elements eines struct ist die gleiche wie die Adresse des struct, es sei denn es ein polymorpher Typ ist.

Aber noch ist nicht alles verloren: Sie können sich darauf verlassen, dass ein Array von charwird immer zusammenhängend sein und keine Verpackung enthalten.

Wenn CHAR_BIT als 8 auf Ihrem System definiert ist (es wahrscheinlich ist), können Sie eine Reihe von 24-Bit-Typen auf einem Array von char modellieren. Wenn es nicht 8 ist, dann wird auch dieser Ansatz nicht funktionieren: Ich würde dann vorschlagen, auf die Inline-Montage zurückzugreifen.

+0

Ich glaube nicht, dass das Betriebssystem sich um Strukturauffüllung kümmert. – PcAF

+0

_Der Compiler und das Betriebssystem behalten sich das Recht vor, die Struktur durch Einfügen von Leerzeichen zwischen den Elementen und selbst am Ende der Struktur aufzuräumen. Einige Compiler haben jedoch den Mechanismus (unter Verwendung von Pragma/Attribut) für gepackte Strukturen. Das gilt jedoch für den Fall von "char; int;" case. Für Bit-Felder wird IMMER die gesamte Größe (INT32 in diesem Fall) Variablen zugewiesen. – anishsane

+0

@PcAF: In der Tat und haben ein wenig umformuliert. – Bathsheba

Verwandte Themen