Go Down

Topic: [gelöst] Warum ergibt sizeof(Data) immer ein Byte mehr? (Read 1 time) previous topic - next topic

HTML-Fan

Hallo!

Ich habe weniger ein Problem, eher eine Frage: Warum in diesem Programm
Code: [Select]
struct Data{
  int16_t x;
  int16_t y;
  uint8_t hp;
};
Data data;
void setup() {
  Serial.begin(115200);
  Serial.println(sizeof(Data));
  uint8_t* pointer = (uint8_t*)&data;
  for(byte i = 0;i < sizeof(Data);i++){
    if(!(pointer[i] >> 4)) Serial.print("0");
    Serial.print(pointer[i], HEX);
    Serial.print("\t");
  }
  Serial.println();
  data.x = 1000;
  data.y = 0x1234;
  data.hp = 100;
  for(byte i = 0;i < sizeof(Data);i++){
    if(!(pointer[i] >> 4)) Serial.print("0");
    Serial.print(pointer[i], HEX);
    Serial.print("\t");
  }
}

void loop() {
  // put your main code here, to run repeatedly:

}

, welches ich auf der Suche nach einer Möglichkeit, die Byte-Werte aus einer Instanz auszulesen, gibt an, dass sizeof(Data) 6 ist, dabei hat Data eine Größe von nur 5 Bytes. Klar, ich könnte einfach überall -1 rechnen, aber mir geht es darum, dass ich wissen will, warum das passiert. Außerdem würde das bedeuten, dass ich bei Arrays aus tausenden kleinen structs tausende Bytes verliere. Ich habe auch mal alle struct-Variablen gelöscht, wodurch die Größe ja 0 sein müsste, und sizeof(Data) ergab 1. Und ich habe es auch mit sizeof(data) probiert, da kam überall das Gleiche (Selbe?) raus. Weiß jemand von euch darüber mehr als ich?

Gruß
HTML-Fan

Tommy56

Auf welchem MC? Auf dem UNO sagt er 5.

Gruß Tommy
"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)

uxomm

Also wenn ich dieses Programm auf einen Arduino UNO lade dann bekomme ich folgende Ausgabe:
Code: [Select]
5
00 00 00 00 00
E8 03 34 12 64

Also sizeof(Data) ist 5.

Arduino IDE 1.8.12 (portable), Windows 10
Always decouple electronic circuitry.

HTML-Fan



(deleted)

#5
May 19, 2020, 02:14 pm Last Edit: May 19, 2020, 02:19 pm by Peter-CAD-HST
(deleted)

Tommy56

#6
May 19, 2020, 02:18 pm Last Edit: May 19, 2020, 02:22 pm by Tommy56
Die 6 kommt beim ESP8266 (Alignment auf 32 Bit Prozessoren)

Gruß Tommy

Edit:
Das gibt dort sogar 12 (auf UNO/MEGA 7):
Code: [Select]

struct Data{
  uint8_t hp;
  int32_t y;
  int16_t x;
};
"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)

Serenifly

#7
May 19, 2020, 02:25 pm Last Edit: May 19, 2020, 02:32 pm by Serenifly
Man kann hier nicht direkt 8 und 32 Bit Prozessoren vergleichen. Das hängt nämlich gerade mit der Speicherbreite/Wortgröße zusammen.

https://de.wikipedia.org/wiki/Speicherausrichtung

Eventuelle Lösung:
https://gcc.gnu.org/onlinedocs/gcc-4.4.4/gcc/Structure_002dPacking-Pragmas.html

Tommy56

Deshalb ergibt der Vergleich ja auch notwendigerweise ohne pack unterschiedliche Größen.

Gruß Tommy
"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)

HTML-Fan

#9
May 19, 2020, 02:52 pm Last Edit: May 19, 2020, 02:55 pm by HTML-Fan
Eventuelle Lösung:
https://gcc.gnu.org/onlinedocs/gcc-4.4.4/gcc/Structure_002dPacking-Pragmas.html
Prima,
Code: [Select]
#pragma pack(1)
löst das "Problem". Hat das irgendwelche Nachteile, macht das z.B. 2-Byte-Operationen einen Strich durch die Berechnung?

Serenifly

Der Speicherzugriff wird eventuell langsamer wenn die Datenstruktur über Speichergrenzen verteilt ist. Das hängt aber von der Prozessorarchitektur ab

HTML-Fan

Das hängt aber von der Prozessorarchitektur ab
Wie ist das denn beim ESP32?

Tommy56

Nach meiner Meinung sollte man pack nur dann verwenden, wenn man Strukturen zwischen verschiedenen Architekturen austauschen will (z.B. ESP8266 <--> NANO). Sonst sollte man den Kompiler seine Optimierungsarbeit machen lassen.

Gruß Tommy
"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)

HTML-Fan

#13
May 19, 2020, 03:09 pm Last Edit: May 19, 2020, 03:11 pm by HTML-Fan

Nach meiner Meinung sollte man pack nur dann verwenden, wenn man Strukturen zwischen verschiedenen Architekturen austauschen will (z.B. ESP8266 <--> NANO).
War nicht der Plan, ich wollte eher sowas wie Speicherplätze realisieren, die ein RAM-Abbild darstellen.
Sonst sollte man den Kompiler seine Optimierungsarbeit machen lassen.
Gibt es die Möglichkeit, dass man nur bei bestimmten "struct"s Cycles gegen RAM tauscht?

Tommy56

Das pack kannst/solltest Du auf jedes struct einzeln anwenden.

Gruß Tommy
"Wer den schnellen Erfolg sucht, sollte nicht programmieren, sondern Holz hacken." (Quelle unbekannt)

Go Up