Forum: Compiler & IDEs Struct Instanz in Struct


von Philipp M. (lord-maricek)


Lesenswert?

Moin,

für mein Programm habe ich ein Struct mit typedef erstellt, von ich dann 
mehrere Instanzen erstellen kann. Ich habe aber noch ein anderes Struct, 
von dem die Instanz in dem ersten Struct erstellt werden soll.

So soll das Später aussehen, aber ich bekomme beim Debuggen immer einen 
Fehler, wenn ich aus s1 herraus auf s2 zugreifen will.
Ich benutzte Visual c++ Express 2010 (ich entwickel das Modul erst am 
Rechner, bevor ich es in das avr-gcc Programm hinzufüge). Da sehe ich 
beim Debuggen, dass die Adresse von s2, 0x00000000 ist.
Ich denke mal, dass ich nur Speicher reserviert habe, ihn aber noch 
nciht benutzten kann.
Wie geht das richtig, ohne, dass ich im Hauptprogramm eine Instanz von 
s2 erstellen muss, und dann in s1->s2 schreibe?

1
//eine Include Datei
2
struct s2{
3
    uint8_t i;
4
};
5
6
typedef s1{
7
    struct s2 * struct2;
8
};
9
10
//Main
11
//...
12
s1 struct1;
13
f(&struct1);
14
//...
15
16
//funktion
17
void f(s1 * const s)
18
{
19
    s->s2->i = 0xff;  //Fehler, zugriffsverletztung
20
}

MfG
Philipp

von Pointer (Gast)


Lesenswert?

Philipp Maricek schrieb:
> typedef s1{
>     struct s2 * struct2;
> };

Du hast noch keinen Speicher für s2 reserviert,sondern nur einen Zeiger 
darauf. Also erst Speicher für s2 schaffen, dem Zeiger zuweisen.

von Karl H. (kbuchegg)


Lesenswert?

Philipp Maricek schrieb:

> Rechner, bevor ich es in das avr-gcc Programm hinzufüge). Da sehe ich
> beim Debuggen, dass die Adresse von s2, 0x00000000 ist.
> Ich denke mal, dass ich nur Speicher reserviert habe, ihn aber noch
> nciht benutzten kann.
> Wie geht das richtig,

Mal eine Frage.

Wenn du ein Objekt (eine Instanz) von s1 erstellen willst, wie schreibst 
du das:

So

  s1  meineS1Variable;


oder schreibst du das so:

  s1 * meineS1Variable;


die erste Variante ist die richtige, denn dort erstellst du eine 
Variable vom Typ s1. Im Grunde ist das genau identisch zu

   int i;

zuerst steht der Datentyp und danach der Name der Variable, die von 
diesem Typ erzeugt werden soll.


   Datentyp * Variablenname;

hingegen erzeugt eine Pointervariable. Eine Pointervariable enthält 
einen Verweis (die Adresse) unter der die eigentliche Information zu 
finden ist. Man könnte auch so sagen: Eine Pointer Variable ist ein 
Zettel, auf dem steht: Der Zauberspruch steht im Buch, 5. Regal, 3. Buch 
von links.
Der Zettel ist NICHT das Buch. Aber auf dem Zettel steht, wo das Buch zu 
finden ist. Das sind Pointer: Verweise, wo die eigentliche Information 
zu finden ist.

Zurück zu Instanzen.
Wenn du also mittels

   Datentyp Variablenname;

eine Instanz vom Typ "Datentyp" erzeugst, was hindert dich daran, dann 
dasselbe in einer struct zu machen


struct s2{
    uint8_t i;
};

struct s1{
    int  member1;
    s2   struct2;
    int  member2;
    s2   noch_eine_struct;
};


Nichts und niemand hindert dich daran. Es gibt lediglich eine 
Einschränkung. Der genau Aufbau von s2 muss bekannt sein, ehe er in s1 
verwendet werden kann. Ist ja auch logisch. Der COmpiler will sofort 
festlegen, wieviel Speicher er für eine s1 - Instanz brauchen wird. Dazu 
muss er aber wissen, wieviel Speicher er für eine s2 Instanz reservieren 
muss. Weiß er das, dann kann er auch den Speicherverbrauch für s1 
festlegen.

von Klaus W. (mfgkw)


Lesenswert?

.. und im Umkehrschluß heißt es, daß man die Variable sinnvoll benennt.
Wenn es keine struct2 ist, sondern ein Zeiger darauf, dann schreibt nur 
der letzte Murkser etwas in der Art:
1
 struct s2 * struct2;  // keine struct2, also wieso sollte es so heißen?

Besser wäre so ein Name:
1
 struct s2 * p_struct2; // Zeiger auf...

Wenn man sich klar ist, was man macht, nimmt man einen passenden Namen.
Umgekehrt: liest man einen sinnvollen Namen, weiß man, was gemeint ist.

von Philipp M. (lord-maricek)


Lesenswert?

Ok, danke,

solangsam bekomme ich das mit Zeigern auf die reihe.

MfG
Philipp

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.