Reihenfolge im struct und Reihenfolge im Speicher

Gast #5361271
Lesenswert?

Hallo,

wie ich schon leidlich erfahren musste liegen die struct-Einträge nicht 
immer lückenlos nebeneinander, sondern es kann sein, dass der 
Prozessorarchitektur geschuldet nach einem boolschen Wert durchaus ein 
Freiraum entstehen kann, bevor der nächste Eintrag mit beispielsweise 
uint16_t gefunden wird.


Nun aber noch eine weitere Frage, gegeben ist folgendes struct:
1
typedef struct
2
{
3
  char Eintrag1[30];
4
  char Eintrag2 [50];
5
  char eintrag3 [20];
6
}MEINSTRCUT;


Liegt der Eintrag2 zwingend hinter dem Eintrag1 im Speicher?
#5361284
Lesenswert?

Struktur schrieb:
>
1
> typedef struct
2
> {
3
>   char Eintrag1[30];
4
>   char Eintrag2 [50];
5
>   char eintrag3 [20];
6
> }MEINSTRCUT;
7
>
>
>
> Liegt der Eintrag2 zwingend hinter dem Eintrag1 im Speicher?

Das hättest du mit minimalem Aufwand selber herausfinden können:

https://www.google.de/search?q=c+struct+memory+layout

gleich der erste Treffer beantwortet deine Frage:

https://stackoverflow.com/questions/2748995/c-struct-memory-layout
Gast #5361288
Lesenswert?

Struktur schrieb:
> nach einem boolschen Wert durchaus ein Freiraum entstehen kann, bevor
> der nächste Eintrag mit beispielsweise uint16_t gefunden wird.
>
> Nun aber noch eine weitere Frage, gegeben

Nicht nur nach bool Werten, sondern nach allen Datentypen. Die 
Reihenfolge ist aber so wie im Code vorgegeben.
Wozu ist das wichtig? Möchtest du den struct über eine Schnittstelle 
verschicken oder in eine Datei speichern und dabei ein bestimmtes Format 
erreichen (ohne Lücken)? Dann lies mal Serialisierung.
Gast #5361293
Lesenswert?

Du kannst ein struct mit dem Attribut PACKED versehen (googlen für 
korrekte Anwendung). Dann werden die Variablen genauso im Speicher 
angelegt, wie du sie angibst, in genau der Reihenfolge ohne irgendwelche 
Lücken.
Persönliche Seite #5361315
Lesenswert?

Es dauert keine fünf Minuten, das mit einem simplen C-Compiler zu 
untersuchen:
1
#include <stdio.h>
2

3
typedef struct
4
{
5
  char Eintrag1[30];
6
  char Eintrag2 [50];
7
  char eintrag3 [20];
8
}MEINSTRCUT;
9

10
int main()
11
{
12
    MEINSTRCUT bla;
13
 
14
    printf("bla      %p\n", &bla);
15

16
    printf("Eintrag1 %p\n", &bla.Eintrag1);
17
    printf("Eintrag2 %p\n", &bla.Eintrag2);
18
    printf("eintrag3 %p\n", &bla.eintrag3);
19

20
    return 0;
21
}

Ergebnis laut https://www.onlinegdb.com/online_c_compiler
1
bla      0x7ffd68e65fc0                                                                                                      
2
Eintrag1 0x7ffd68e65fc0                                                                                                      
3
Eintrag2 0x7ffd68e65fde                                                                                                      
4
eintrag3 0x7ffd68e66010

Warum traut sich heutzutage niemand mehr, Vermutungen einfach 
auszuprobieren?
Gast #5361319
Lesenswert?

Rufus Τ. F. schrieb:
> Warum traut sich heutzutage niemand mehr, Vermutungen einfach
> auszuprobieren?

Nur weil in C(++) etwas bei einem Versuch funktioniert, heißt das noch 
lange nicht dass es korrekt im Sinne des Standards ist, und daher unter 
allen Bedingungen funktioniert. Gerade solche Dinge wie Speicher-Layouts 
sind da ein gefährliches Pflaster.
Persönliche Seite #5361348
Lesenswert?

Ich bin mir nicht sicher, ob der Threadstarter eine allgemeingültige 
Aussage, die für alle Compiler, Prozessorarchitekturen und Wetterlagen 
dieses Universums gilt, oder ob er vielleicht auch nur eine vage 
Vorstellung davon gewinnen möchte, wie Objekte im Speicher angeordnet 
werden.

Struktur schrieb:
> Liegt der Eintrag2 zwingend hinter dem Eintrag1 im Speicher?

Diese Frage kann sich nämlich auch auf die Reihenfolge beziehen. Ginge 
es nur ums Alignment, hätte die Frage anders gelautet, denn der 
Threadstarter hat durchaus verstanden, daß es eine entsprechende 
Ausrichtung von Strukturelementen geben kann.
Moderator Persönliche Seite #5361361
Lesenswert?

Rufus Τ. F. schrieb:
> Diese Frage kann sich nämlich auch auf die Reihenfolge beziehen.

Ich abe es auch so verstanden, dass die Frage ausschließlich die 
Reihenfolge betraf. Der TO schrieb auch im Eingangsbeitrag:

"dass der Prozessorarchitektur geschuldet nach einem boolschen Wert 
durchaus ein Freiraum entstehen kann, bevor der nächste Eintrag mit 
beispielsweise uint16_t gefunden wird."

Über die Lücken wusste er also Bescheid.

Und wenn er Google nach "C struct order" angeworfen hätte, dann hätte 
ihm bereits der erste Eintrag geholfen:

https://stackoverflow.com/questions/2748995/c-struct-memory-layout?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa

--------------------
C99 §6.7.2.1:

12 Each non-bit-field member of a structure or union object is aligned 
in an implementation- defined manner appropriate to its type.

13 Within a structure object, the non-bit-field members and the units in 
which bit-fields reside have addresses that increase in the order in 
which they are declared. A pointer to a structure object, suitably 
converted, points to its initial member (or if that member is a 
bit-field, then to the unit in which it resides), and vice versa. There 
may be unnamed padding within a structure object, but not at its 
beginning.
--------------------

Die Reihenfolge ist in C also garantiert - abweichend zu anderen 
Programmiersprachen wie z.B. C#.

Ich selbst würde aber niemals Annahmen über Positionen in einer struct 
machen, denn es gibt immer eine portable Lösung.
#5361394
Lesenswert?

Ich weiß gar nicht ob das heute überhaupt noch nötig ist. Soweit mir 
bekannt packen die Compiler die Daten in der - für den Rechner - 
"natürlichen" Anordnung.
Hat man also einen 16 Bit Rechner, so werden, falls möglich, 
char-Variablen immer an Wort-Grenzen abgelegt. So ist der Zugriff zwar 
schneller, aber die Speicherausnutzung schlechter. Seit dem es dieses 
Verhalten gibt, gibt es auch das Schlüsselwort "packed".
Gast #5361423
Lesenswert?

z.B. MSP CodeCoposer 16.9 Kapitel 6.2.1 Data Type Storage

struct

Members are stored as their individual types require.

Multiple of 8 bits aligned to boundary of largest member type; members 
are stored and aligned as their individual types require.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren