C Array Payload (size as needed)?

3 Antworten

Schau Dir erstmal das heir an:

https://en.wikipedia.org/wiki/Flexible_array_member

Das wäre die Variante, wie sie in C99 Teil des Standards wurde. Zuvor mußte es eben ein Array der Größe 1 sein und nein einfach ein char pointer tut es nicht, denn data soll kein pointer sein, sondern ein beliebig großes Feld von Bytes (chars).

struct {
int size;
unsigned char data[1];
}

Hier werden die Daten quasi in die struct eingebettet.

struct {
int size;
unsigned char *;
}

Hier würde data auf einen dedizierten Speicherbereich zeigen, den ich z.B. auch mit realloc verändern kann.

Kommen wir zur eigentlichen Frage.

a -> data <=> (*a).data

Ein Array wird allgemein durch seind Basisadresse dargestellt data ist also die Speicheradresse an der das Array innerhalb der structure liegt.

Ich caste mir die also zu einem int pointer um und dereferenziere dann, weil ich ja an dieser Adresse den Wert ablegen will.

Verlassen wir mal kurz den generischen Bereich und nehmen ein intuitiveres(?) Beispiel:

struct vect{
    int x;
    int y;
    int z;
};

struct vect vectors[100];

Soweit so klar, ich habe ein Array, das 100 vect beinhaltet, doch was, wenn die Zahl nicht fix ist?

struct varr{
     int len;
     strcut vect vector[];
};

struct varr *myvecs=malloc(sizeof(struct varr)+100*sizeof(struct vect));
myvecs->len=100;
for (int i=0;i<100;++i) myvecs->vector[i].x=1;

Na und wenn ich verschiedene Typen haben will, dann nehme ich eben ein array von chars und muß das für den konkreten Typ zurechtcasten.

Und ich möchte noch etwas verlinken:

https://c-faq.com/struct/structhack.html

Zunächst mal ist a->data in C ein Array. Das ganze geht eben nur wegen der Pointer Array dualität in C. Wesentlichen besser wäre es hier data nicht als Array sondern als unsigned char* data; zu definieren.

*(int*)a->data sagt jetzt caste den unsigend char Pointer data aus der struct a als integer Pointer. Anschließend wird der Integer Pointer dereferenziert wodurch er zu einem int wird.

Ist zwar möglich aber kann schnell zu schwer findbaren Fehlern führen, daher am besten nicht angewöhnen.

Butzti 
Fragesteller
 22.07.2022, 23:59

Danke bre <3

0

Fang mal langsam an:

  1. char c; // reserviert ein Byte.
  2. char * cp = &c; // ist dessen Adresse.
  3. int *ip = (int *) cp; // ist dieselbe Adresse, aber „geeignet“ für int-Werte.
  4. *ip = 42; überschreibt das Byte (und noch mehr!) an dieser Adresse.

Alles in einem Rutsch: *(int*)&c = 42;

Das geht prinzipiell mit jedem Datentyp. Nimmt man in 1. statt char ein Array char[1],dann spart man sich das '&' in Punkt 2, weil ein Arraybezeichner (fast) immer automatisch in einen Zeiger auf das erste Element umgewandelt wird.