Forum: Mikrocontroller und Digitale Elektronik Strukt auf einen Pointer aus einem Strukt setzen


von C. H. (hedie)


Lesenswert?

Ich alloziieren Speicher mit malloc.
Den erhaltenen Pointer speicher ich in einem Strukt ab.
1
typedef struct
2
{
3
  uint8_t    ID;
4
  uint8_t    Typ;
5
  uint8_t*  Addr;
6
}  uGUI_str_ID;
7
//....
8
uGUI_ObjectID[ID_Counter].Addr = malloc(uGUI_def_ObjSize[ObjectType]*sizeof(uint8_t));


Nun möchte ich an einer anderen Stelle, ein Strukt an dieser 
Speicherstelle initialisieren.

Dies habe ich wie folgt versucht:
1
//Struct Instanz erstellen
2
struct uGUI_str_button *info;
3
info = &uGUI_ObjectID[objectID].Addr;

Doch so wie oben funktioniert es laut Debugger nicht.
Die Adresse von "info" ist nicht dieselbe wie jene welche in 
uGUI_ObjectID[objectID].Addr steht.

Kann mir jemand einen Tipp geben?
Danke!

von Karl H. (kbuchegg)


Lesenswert?

Claudio H. schrieb:

> info = &uGUI_ObjectID[objectID].Addr;

Warum schon wieder ein &

Noch mal.

Wenn du eine Pointer Variable hast, dann steht in ihr bereits die 
Adresse des Speichers drinnen! Da braucht es keinen & mehr.

Eine Pointer Variable ist so gesehen auch nicht anders als ein int.

Schreibst du
1
  int i = 5;
2
3
  j = i;

dann ist durch die Nennung von i in
1
  j = i;
automatisch klar, dass der Inhalt von i (die 5) gemeint ist.

Nicht anders bei Pointern.
1
  int j = 8;
2
  int* Addr;
3
4
  Addr = &j;   // hier braucht es den &
5
               // den wir wollen ja nicht den Inhalt von j, sondern die
6
               // Adresse von j
7
8
  int* Addr2;
9
10
  Addr2 = Addr;  // aber hier braucht es keinen &!
11
                 // Denn der Inhalt der Variablen Addr ist ja die gesuchte
12
                 // Speicheradresse!
13
                 // In Addr2 steht danach dieselbe Speicheradresse wie in Addr
14
                 // Beide Pointer verweisen auf den gleichen Speicher, weil
15
                 // sie ja als Inhalt dieselbe Adresse halten.


> Die Adresse von "info" ist nicht dieselbe wie jene welche in
> uGUI_ObjectID[objectID].Addr steht.

Du sagst es hier ja selber: "drinnen steht"!

"Drinnen steht" ist aber niemals ein &
EIn & bezieht sich immer auf die Variable seber:
1
     i
hier ist der Inhalt der Variablen gemeint. Sozusagen "was in ihr drinnen 
steht"
1
    &i
hier wird eine Aussage über die Variable selber gemacht: Wo steht das i 
im Speicher?

von C. H. (hedie)


Lesenswert?

Karl Heinz schrieb:
> Warum schon wieder ein &

Ich habe es zuvor so versucht:
1
struct uGUI_str_button *info;
2
    info = uGUI_ObjectID[objectID].Addr;

In Addr steht: 0x20000c98

Laut Debugger ist nach diesem Befehl die Adresse von info 0x000000000;

Addr ist ein Pointer vom Typ uint8_t

von Karl H. (kbuchegg)


Lesenswert?

Claudio H. schrieb:

> Ich habe es zuvor so versucht:
>
>
1
> struct uGUI_str_button *info;
2
>     info = uGUI_ObjectID[objectID].Addr;
3
>

Das wird nicht kompiliert haben.
Denn ohne Cast geht diese Zuweisung nicht.

Bischen sorgfältiger arbeiten!

von C. H. (hedie)


Lesenswert?

Karl Heinz schrieb:
> Bischen sorgfältiger arbeiten!

Das ist ein relativ neues Gebiet für mich.
Von daher ist sorgfältig Arbeiten noch nicht möglich...


Wie Caste ich denn hier?

Mit: (struct uGUI_str_button *) ?

von Karl H. (kbuchegg)


Lesenswert?

Claudio H. schrieb:
> Karl Heinz schrieb:
>> Bischen sorgfältiger arbeiten!
>
> Das ist ein relativ neues Gebiet für mich.
> Von daher ist sorgfältig Arbeiten noch nicht möglich...
>
>
> Wie Caste ich denn hier?
>
> Mit: (struct uGUI_str_button *) ?

Genau so sieht ein Cast in C aus. Solltest du aber schon wissen, wenn du 
mit dynamischen Datenstrukturen rummachst.

Mit etwas mehr Wissen und weniger Probieren an die Sache rangehen.
Du bist jetzt an einem Punkt angelangt, an dem blindes rumprobieren 
gefährlich wird. D.h. jetzt muss man sich schon einigermassen sicher 
sein, was die ganzen Sonderzeichen eigentlich machen und was eigentlich 
richtig wäre. Die Zeiten an denen man dann einfach mal irgendwelche 
Zeichen in den Code einwirft sind vorbei.

Was glaubst du, warum ich immer darauf dränge, dass die Leute C Bücher 
haben und die auch durchgearbeitet haben?

von Noch einer (Gast)


Lesenswert?

> Eine Pointer Variable ist so gesehen auch nicht anders als ein int.

Hat eigentlich mal jemand zusammengezählt, wie viele Mannjahre an 
Fehlersuche diese Definition verursacht?

von Karl H. (kbuchegg)


Lesenswert?

Noch einer schrieb:
>> Eine Pointer Variable ist so gesehen auch nicht anders als ein int.
>
> Hat eigentlich mal jemand zusammengezählt, wie viele Mannjahre an
> Fehlersuche diese Definition verursacht?

Was genau meinst du mit dem aus dem Zusammenhang gerissenen Zitat?
Und warum soll das 'Mannjahre an Fehlersuche' generieren, wenn für 
Variablentypen wie int, double, long, Pointer gilt, dass ihre Nennung in 
einem Ausdruck automatisch bedeutet, dass man sich damit auf den Inhalt 
der Variablen bezieht. Ein Inhalt der bei int eine Zahl ist, bei einem 
Pointer aber eine Speicheradresse, was nicht weiter verwundert, da ja 
eine Pointer Variable so definiert ist, dass es sich dabei um eine 
Variable handelt, die eine Speicheradresse speichern kann. So wie eben 
eine int Variable definiert ist als eine Variable die einen Integer 
speichern kann.

Also: Was genau meinst du mit deiner Aussage?

von Marc S. (marc_s86)


Lesenswert?

Karl Heinz schrieb:
> Also: Was genau meinst du mit deiner Aussage?

ich denke er meint damit dass er zu faul ist C zu verstehen und das 
deshalb die sprache schuld ist dass sie nicht tut was er will

von C. H. (hedie)


Lesenswert?

Ich wäre froh, wenn wir uns wieder auf das ursprüngliche Thema 
konzentrieren könnten.

Nicht jeder hat ein C-Buch durchgearbeitet.
Wäre jeder Profi in allem, dann bräuchte es ja dieses Forum nicht!

von Karl H. (kbuchegg)


Lesenswert?

Claudio H. schrieb:
> Ich wäre froh, wenn wir uns wieder auf das ursprüngliche Thema
> konzentrieren könnten.
>
> Nicht jeder hat ein C-Buch durchgearbeitet.
> Wäre jeder Profi in allem, dann bräuchte es ja dieses Forum nicht!

Möööp
Damit disqualifizierst du dich selbst.

Das man Dinge lernen muss ist klar. Lernbehelfe aber zu verweigern ist 
nicht ok.
Gerade in einer Programmiersprache hängt auf die eine oder andere Art 
und Weise alles mit allem zusammen. So manches Detail erschliesst sich 
erst im Zusammenhang mit anderen Details.
Mit in Foren zusammengeschnorrtem Achtelwissen kommt man da nicht weit.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Claudio H. schrieb:
> Nicht jeder hat ein C-Buch durchgearbeitet.

Das ist aber Voraussetzung, wenn man mit C-Programmiererei zu etwas 
kommen will.

Verweigerungshaltung à la "Ich will in C programmieren, aber kein C-Buch 
anfassen" bringt Dich nicht weiter.

von Marc S. (marc_s86)


Lesenswert?

Claudio H. schrieb:
> Ich wäre froh, wenn wir uns wieder auf das ursprüngliche Thema
> konzentrieren könnten.

Dann erzähl mal ob das mit dem Casten funktioniert hat

von C. H. (hedie)


Lesenswert?

Es ist sehr schade, dass in diesem Forum ein solch unangebrachtes 
Verhalten nun auch von Moderatoren praktiziert wird.

von C. H. (hedie)


Lesenswert?

Marc S. schrieb:
> Dann erzähl mal ob das mit dem Casten funktioniert hat

//Struct Instanz erstellen
    struct uGUI_str_button *info;
    info = (struct uGUI_str_button *)uGUI_ObjectID[objectID].Addr;

Dies führt ebenfalls zu einer Adresse:

info 0x0000000;

von Karl H. (kbuchegg)


Lesenswert?

Claudio H. schrieb:
> Marc S. schrieb:
>> Dann erzähl mal ob das mit dem Casten funktioniert hat
>
> //Struct Instanz erstellen
>     struct uGUI_str_button *info;
>     info = (struct uGUI_str_button *)uGUI_ObjectID[objectID].Addr;
>
> Dies führt ebenfalls zu einer Adresse:
>
> info 0x0000000;

langsam.
compilierst du mit aktiviertem Optimizer?

Wenn ja, dann darfst du deinem Debugger nicht alles glauben. Denn der 
Optimizer hat dein Programm umgestellt und so manche Anweisung wird erst 
an einer ganz anderen Stelle dann tatsächlich ausgeführt.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Claudio H. schrieb:
> Es ist sehr schade, dass in diesem Forum ein solch unangebrachtes
> Verhalten nun auch von Moderatoren praktiziert wird.

Nochmal langsam.

Du kommst mit einer C-spezifischen Frage an, und lässt deutlich 
erkennen, daß Du keine Lust hast, Dich mit C zu beschäftigen, aber Deine 
Probleme hier im Forum von anderen Leuten lösen lässt, und hältst Kritik 
an dieser Einstellung für unangemessen?

Echt jetzt?

von Noch einer (Gast)


Lesenswert?

> Also: Was genau meinst du mit deiner Aussage?

C erlaubt
int i = &i;

würde es nur
int *ip = &i;

erlauben, währe der Fehler, über den wir hier diskutieren gar nicht 
möglich.

von Marc S. (marc_s86)


Lesenswert?

Noch einer schrieb:
>> Also: Was genau meinst du mit deiner Aussage?
>
> C erlaubt
> int i = &i;
>
> würde es nur
> int *ip = &i;
>
> erlauben, währe der Fehler, über den wir hier diskutieren gar nicht
> möglich.

und warum sollte es so eine einschränkung geben?

von C. H. (hedie)


Lesenswert?

Karl Heinz schrieb:
> compilierst du mit aktiviertem Optimizer?

Ja!

Karl Heinz schrieb:
> langsam.
> compilierst du mit aktiviertem Optimizer?

Ja...

Karl Heinz schrieb:
> Wenn ja, dann darfst du deinem Debugger nicht alles glauben. Denn der
> Optimizer hat dein Programm umgestellt und so manche Anweisung wird erst
> an einer ganz anderen Stelle dann tatsächlich ausgeführt.

Der Controller stürzt ab, sobald ich etwas in das Strukt hineinschreibe.

von Karl H. (kbuchegg)


Lesenswert?

Noch einer schrieb:
>> Also: Was genau meinst du mit deiner Aussage?
>
> C erlaubt
> int i = &i;

Alle Compiler, die ich kenne werfen da eine Warnung.
'makes integer from pointer without a cast'

Warnungen sollte man eben nicht ignorieren.

von Karl H. (kbuchegg)


Lesenswert?

Claudio H. schrieb:
> Karl Heinz schrieb:
>> compilierst du mit aktiviertem Optimizer?
>
> Ja!

dann schalte den mal aus.

>> Wenn ja, dann darfst du deinem Debugger nicht alles glauben. Denn der
>> Optimizer hat dein Programm umgestellt und so manche Anweisung wird erst
>> an einer ganz anderen Stelle dann tatsächlich ausgeführt.
>
> Der Controller stürzt ab, sobald ich etwas in das Strukt hineinschreibe.

Das kann viele andere Ursachen haben.
Die prominenteste besteht darin, dass bereits in Addr eine 0 drinn 
steht.

Die Zuweisung ist definitiv nicht das Problem. Denn da wird nur ein 
Zahlenwert (die Adresse) von A nach B kopiert und intern vermerkt, dass 
diese Adresse jetzt einen anderen Datentyp haben soll. Mehr passiert da 
nicht.

von Karl H. (kbuchegg)


Lesenswert?

> währe der Fehler, über den wir hier diskutieren

Äh. Nein.
Wir 'disuktieren' hier über ein ganz anderes Problem.
Die mögliche Zuweisung eines Pointers an einen int ist NICHT das 
Problem. Denn int sind hier überhaupt nicht im Spiel. Es geht nur und 
ausschliesslich um Pointer.

von Noch einer (Gast)


Lesenswert?

> Warnungen sollte man eben nicht ignorieren.

Ja, diesen Satz am besten auf die Titelseite jedes C-Lehrbuches.

von Marc S. (marc_s86)


Lesenswert?

von welcher platform reden wir hier eigentlich?

von Noch einer (Gast)


Lesenswert?

> Die mögliche Zuweisung eines Pointers an einen int ist NICHT das
Problem.

Genau genommen hat Claudio einem uint8_t** einem uGUI_str_button* 
zugewiesen. Und die Warnung ignoriert.

von C. H. (hedie)


Lesenswert?

Karl Heinz schrieb:
> dann schalte den mal aus.

Gut, ich hab die Optimierung ausgeschaltet.

Nun funktioniert das ganze auch!

Vielen Dank!

von Karl H. (kbuchegg)


Lesenswert?

Noch einer schrieb:
>> Die mögliche Zuweisung eines Pointers an einen int ist NICHT das
> Problem.
>
> Genau genommen hat Claudio einem uint8_t** einem uGUI_str_button*
> zugewiesen. Und die Warnung ignoriert.

Genau genommen ist das in dem Fall aber keine Warnung sondern ein 
handfester Error.

von C. H. (hedie)


Lesenswert?

Marc S. schrieb:
> von welcher platform reden wir hier eigentlich?

Von einem Attiny4

von Karl H. (kbuchegg)


Lesenswert?

Claudio H. schrieb:
> Marc S. schrieb:
>> von welcher platform reden wir hier eigentlich?
>
> Von einem Attiny4

Und auf dem benutzt du einen malloc?

Du bist mutiger als ich dachte. Das würde nicht mal ich mir trauen.
Nicht mit heissen 32 Bytes SRAM.

von Noch einer (Gast)


Lesenswert?

> Genau genommen ist das in dem Fall aber keine Warnung sondern ein
> handfester Error.

Es sollte in der Sprachdefinition ein Handfester Fehler sein.

void main(int argc, void *argv) {
  typedef int uint8_t;
  typedef struct
  {
    uint8_t*  Addr;
  }  uGUI_str_ID;
  uGUI_str_ID uGUI_ObjectID[13];
  struct uGUI_str_button *info;
  info = &uGUI_ObjectID[0].Addr;
}

gcc a.c
a.c: In Funktion »main«:
a.c:9:8: Warnung: Zuweisung von inkompatiblem Zeigertyp [standardmäßig 
aktiviert]

von Karl H. (kbuchegg)


Lesenswert?

Noch einer schrieb:
>> Genau genommen ist das in dem Fall aber keine Warnung sondern ein
>> handfester Error.
>
> Es sollte in der Sprachdefinition ein Handfester Fehler sein.

Muss mich entschuldigen.
Bin von C++ verdorben.

In C ist das tatsächlich kein Error.

von Karl H. (kbuchegg)


Lesenswert?

Karl Heinz schrieb:
> Claudio H. schrieb:
>> Marc S. schrieb:
>>> von welcher platform reden wir hier eigentlich?
>>
>> Von einem Attiny4
>
> Und auf dem benutzt du einen malloc?
>
> Du bist mutiger als ich dachte. Das würde nicht mal ich mir trauen.
> Nicht mit heissen 32 Bytes SRAM.

Also:
langer Rede, kurzer Sinn.

Du musst das anders aufziehen. malloc ist tabu, statt dessen wird ALLES 
statisch definiert. Wenn du unterschiedliche STrukturtypen hast, dann 
legst du die mittels einer union alle übereinander. Alle Arrays werden 
mit ihrer maximalen Länge definiert, die so bemessen ist, dass es gerade 
noch in den Speicher passt. Eine Pointer Variable in einer Struktur 
kannst du dir nicht leisten - kostet zu viel Speicher.

Und dann darfst du beten, dass noch genügend RAM für den Runtime-Stack 
übrig bleibt. Bei heissen 32 Byte zählt jedes verbrauchte Bit.

von Karl H. (kbuchegg)


Lesenswert?

Was ist los?
Kein Kommentar dazu?


Im Ernst. So ein kleines Ding in C zu programmieren ist eine echte 
Herausforderung. Normalerweise würde ich da nicht zu C greifen, sondern 
in Assembler rangehen. Denn hier brauchst du tatsächlich die Kontrolle 
über jedes einzelne Byte im SRAM. Und selbst dann ist das schwierig und 
erfordert Übersicht und genaue Planung der verwendeten Resourcen.

Oder war der Tiny 4 nur ein Scherz? Ich geh mal davon aus, dass es das 
nicht war.

von Marc S. (marc_s86)


Lesenswert?

aufgrund der variablen namen kann ich mir eigentlich einen tiny4 nicht 
vorstellen o.0 eine gui und funktionalität auf einem 6 pinner mit 
512byte flash?

von C. H. (hedie)


Lesenswert?

Sorry, ja hatte mich vertan...

Es ist ein STM32

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.