Forum: Compiler & IDEs struct über ein byte-array legen


von Simon K. (simon) Benutzerseite


Lesenswert?

Huhu,

Ich benutze folgendes Konstrukt, um ein 512-Byte Puffer zu erhalten und
wahlweise 3 verschiedene "Schablonen" darauf aufzulegen.
1
  u08 buffer[512];
2
  struct t_dirdata *p_dirdata = (struct t_dirdata *) &buffer;
3
  struct t_filedata *p_filedata = (struct t_filedata *) &buffer;
4
  struct t_headerpage *p_headerpage = (struct t_headerpage *) &buffer;

Ich denke mal ihr wisst was ich meine.

Nunja, da das ganze sehr verwirrend aussehen kann, wollte ich frage, ob
man das nicht irgndwie anders realisieren könnte.

Vielen Dank schonmal

von Karl H. (kbuchegg)


Lesenswert?

Kann man (wenn auch nicht standardkonform (*)

union Data {
  t_dirdata    DirData;
  t_filedata   FileData;
  t_headerpage HeaderPage;
};

Davon eine Variable gemacht:

union Data Daten;

und schon teilen sich
  Data.DirData
  Data.FileData
  Data.HeaderPage

ein und denselben Speicher. Sie liegen quasi übereinander.

(*)
Das ist deshalb nicht standardkonform, weil du vom C Standard
nur die Zusicherung kriegst, dass du Daten aus einer Union
nur über den gleichen Weg wiederlesen kannst über den sie
auch geschrieben wurden. In der Praxis funktioniert obiges
allerdings auf allen Compilern die ich kenne.

Ach ja: Wenn du magst kannst du ja auch noch zusätzlich das
512-er Buffer Array in die union mit aufnehmen.

von Simon K. (simon) Benutzerseite


Lesenswert?

Vielen Dank schonmal für deine Antwort!.

Die Möglichkeit sieht wirklich schon zivilisierter aus. Ich denke mal
so werde ich das machen

von Simon K. (simon) Benutzerseite


Lesenswert?

Nochmal eine Frage,
Kann es sein, dass wenn die Structs, die in der Union sind,
gleichnamige member haben, es Probleme geben kann?

Folgende Meldung spuckt der Compiler bei folgendem Code aus:
1
//Header-page on disk
2
struct t_diskheader
3
{
4
  u08 diskname[64];  //Name of disk
5
  u32 p_root;      //Pointer to root-dir
6
  u32 disksize;    //size of disk in kb
7
};
8
9
//a headerpage is a page, which contains file-/dirheader-information
10
only
11
struct t_headerpage
12
{
13
  u32 p_nextpage;    //pointer to next page in chain
14
  u16 validbytes;    //# of valid bytes in this page
15
  u16 hdrreserved;  //2 bytes reserved
16
17
  u32 tcreate;    //time of creation
18
  u32 tlastaccess;  //time of last access
19
  u32 tlastchange;  //time of last change
20
  u08 objname[256];  //256-char name of file/dir
21
  u32 p_parent;    //pointer to parent dir
22
  u08 headertype;    //0 = DIR, 1 = FILE
23
  u08 attribflags;  //Atrribute of file/dir
24
  u32 filesize;    //size of file (if dir, then filesize = 0!)
25
  u08 reserved[226];  //Reserved
26
};
27
28
//t_dirdata is a page, which contains 126 dir entrys
29
struct t_dirdata
30
{
31
  u32 p_nextpage;    //pointer to next page in chain
32
  u16 validbytes;    //# of valid bytes in this page
33
  u16 hdrreserved;  //2 bytes reserved
34
35
  u32 dir_entry[126];  //holds pointer to linked dir/file. max 126
36
};
37
38
//t_filedata is a page, which holds 504b filedata
39
struct t_filedata
40
{
41
  u32 p_nextpage;    //pointer to next page in chain
42
  u16 validbytes;    //# of valid bytes in this page
43
  u16 hdrreserved;  //2 bytes reserved
44
45
  u08 data[504];    //504b + 8 bytes header = 512byte
46
};
47
48
//Union of one page.
49
union u_page
50
{
51
  u08 raw[512];
52
  struct t_filedata;
53
  struct t_dirdata;
54
  struct t_headerpage;
55
  struct t_diskheader;
56
};

error C2020: 'p_nextpage' : 'union' member redefinition
error C2020: 'validbytes' : 'union' member redefinition
error C2020: 'hdrreserved' : 'union' member redefinition

Ist es vielleicht sinnvoll, eine neue struct mit den jeweils 3 gleichen
membern zu machen und diese jeweils in die structs t_headerpage,
t_dirdata und t_filedata einzubeziehen?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Du solltest keine anonymen Elemente in der Union verwenden. Also nicht

union u_page
{
  u08 raw[512];
  struct t_filedata;
  struct t_dirdata;
  struct t_headerpage;
  struct t_diskheader;
};

sondern

union u_page
{
  u08 raw[512];
  struct t_filedata filedata;
  struct t_dirdata dirdata;
  struct t_headerpage headerpage;
  struct t_diskheader diskheader;
};

von Simon K. (simon) Benutzerseite


Lesenswert?

ah klatsch. Das habe ich übersehen :-) Die Elemente in der Union
müssen ja schließlich einen Namen haben, damit man sie ansprechen
kann.

Dank dir Rufus!

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.