Forum: Compiler & IDEs Struct als Zeiger übergeben


von verwirrter Frickler (Gast)


Lesenswert?

Mal auf's Wesentliche abgespeckt. Vor main:
1
struct someStuff_t{
2
    int SDM120reg;
3
 // char serial[20];
4
    };
5
6
void test(struct someStuff_t * xy){
7
 xy->SDM120reg = 30001;
8
//strcpy (xy->serial, "/dev/ttyS0");
9
}
10
11
12
int main (void){
13
    someStuff_t *someStuff;
14
    test(someStuff);
15
16
    return 0;
17
}
Das führt dazu, daß das Programm mit einer Meldung über einen internen 
Fehler sofort abgebrochen wird.
Was mache ich da falsch...? Kann es sein, daß die Compiler-Settings 
vielleicht irgendwie falsch eingestellt ist? Compiler ist 
mingw32-g++.exe für Win 10 unter Code Blocks mit Ausgabe im DOS-Fenster; 
alle Compiler-Settings default und seit Wochen ohne Probleme...

von jz23 (Gast)


Lesenswert?

[ ] Du möchtest in einem Programmierbuch deiner Wahl nochmal das Kapitel 
über Zeiger durchlesen

von Der Pointler (Gast)


Lesenswert?

Du versuchst einen nicht initialisierten Pointer zu dereferenzieren, das 
geht zu 99.999999% in die Hose.

von Garcon (Gast)


Lesenswert?

Tip: worauf zeigt
1
someStuff
?

von Andreas S. (Firma: Schweigstill IT) (schweigstill) Benutzerseite


Lesenswert?

Wenn Du Dich auch nur eine Sekunde Deines Lebens mit der für die 
Verwendung von Zeigern erforderlichen Gedanken über die 
Speicherverwaltung beschäftigt hättest, dann wäre Dir die Sache völlig 
klar. Aber leider scheint heutzutage eine Beschäftigung mit den 
Grundlagen bei vielen, nicht allen(!), ziemlich verpönt zu sein. Statt 
sich das nötige Wissen selbst zu erarbeiten, wird dann einfach auf 
irgendwelche Webforen zurückgegriffen.

Aber natürlich ist das alles nicht Deine Schuld, sondern der böse, böse 
Compiler ist dafür verantwortlich.

Genau diese Art von Unverständnis über die Verwendung von Zeigern führte 
übrigens dazu, dass ehemalige Kollegen völlig zu Recht die Entlassung 
eines anderen Kollegen forderten, da sie es leid waren, dessen Fehler 
immer wieder auszubügeln. Dummerweise machen sich derartige Fehler 
häufig nicht an der Stelle bemerkbar, an der sie verursacht werden, 
sondern ggf. sogar in ganz anderen Modulen der Software.

von verwirrter Frickler (Gast)


Lesenswert?

>Du versuchst einen nicht initialisierten Pointer zu dereferenzieren
Aaahhhh! Natürlich, ich Depp!

Das hier hat geholfen.
1
    someStuff_t *someStuff, st;
2
    someStuff = &st;

von Garcon (Gast)


Lesenswert?

verwirrter Frickler schrieb:
> Du versuchst einen nicht initialisierten Pointer zu
> dereferenzieren
>
> Aaahhhh! Natürlich, ich Depp!
>
> Das hier hat geholfen.    someStuff_t *someStuff, st;
>     someStuff = &st;

Ich wollte zuerst was zu Schweigstills Kommentar schreiben aber das hat 
mich dann doch davon abgehalten, weil er scheinbar doch klüger ist und 
recht hat...

Tldr: Überdenk deine Lösung nochmal...

von Der Pointler (Gast)


Lesenswert?

verwirrter Frickler schrieb:
> Das hier hat geholfen.    someStuff_t *someStuff, st;
>     someStuff = &st;

Ich wage zu bezweifeln, dass dein Compiler das ohne zu motzen 
akzeptiert.

von verwirrter Frickler (Gast)


Lesenswert?

Autor: Andreas Schweigstill (Firma: Schweigstill IT) (schweigstill) 
schrieb:
>Wenn Du Dich auch nur eine Sekunde Deines Lebens mit der für die
>Verwendung von Zeigern erforderlichen Gedanken über die
>Speicherverwaltung beschäftigt hättest

Sag doch nicht so was. Ich frickle seit Jahren vor mich hin und schaue 
ab und zu auch tatsächlich in das Ritchie-Buch - aber wenn man nur alle 
Schaltjahr Code schreibt, dann vergisst man halt einiges...

Anyway, Montessori-Pädagogik (hilf, damit du dir selbst helfen kannst) 
wie von Garcon praktiziert ist bei weitem besser als hier deinen Frust 
über einen unfähigen Kollegen abzulassen...

von Nop (Gast)


Lesenswert?

Der Pointler schrieb:
> verwirrter Frickler schrieb:
>> Das hier hat geholfen.    someStuff_t *someStuff, st;
>>     someStuff = &st;
>
> Ich wage zu bezweifeln, dass dein Compiler das ohne zu motzen
> akzeptiert.

Ich würde das nicht wagen. Die Deklaration deklariert erst einen Zeiger 
auf das struct und dann ein struct selber. Der Asterisk bindet sich an 
den Variablennamen und nicht an den Datentyp. Es werden hier also 
keineswegs zwei Zeiger deklariert.

von jz23 (Gast)


Lesenswert?

Schön ist das aber nicht und wozu man überhaupt einen Zeiger an der 
Stelle benutzt ist mir auch nicht klar.

von Nop (Gast)


Lesenswert?

jz23 schrieb:
> Schön ist das aber nicht

Stimmt, und genau weil man beim schnellen Lesen so eine Art Deklaration 
mißversteht, deklariere ich Zeiger und Daten nie auf diese Weise in 
derselben Zeile.

> und wozu man überhaupt einen Zeiger an der Stelle benutzt ist mir auch nicht 
klar.

Klar ist der überflüssig, man kann auch direkt mit &st rangehen.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

verwirrter Frickler schrieb:
1
typedef struct
2
{
3
     int SDM120reg;
4
} someStuff_t;
5
6
void test (someStuff_t *xy)
7
{
8
  xy->SDM120reg = 30001;
9
}
10
11
int main (void)
12
{
13
      someStuff_t someStuff;
14
      test (&someStuff);
15
16
      return 0;
17
}

von Jobst Q. (joquis)


Lesenswert?

Nop schrieb:
> Der Pointler schrieb:
>> verwirrter Frickler schrieb:
>>> Das hier hat geholfen.    someStuff_t *someStuff, st;
>>>     someStuff = &st;
>>
>> Ich wage zu bezweifeln, dass dein Compiler das ohne zu motzen
>> akzeptiert.
>
> Ich würde das nicht wagen. Die Deklaration deklariert erst einen Zeiger
> auf das struct und dann ein struct selber. Der Asterisk bindet sich an
> den Variablennamen und nicht an den Datentyp. Es werden hier also
> keineswegs zwei Zeiger deklariert.

Soll ja wohl auch nicht. Neben dem Zeiger wird ein Struct selbst, also 
eine Speicherstelle deklariert. So funktioniert es, mit zwei Pointern 
nicht.

von Nop (Gast)


Lesenswert?

Jobst Q. schrieb:

> Soll ja wohl auch nicht. Neben dem Zeiger wird ein Struct selbst, also
> eine Speicherstelle deklariert. So funktioniert es, mit zwei Pointern
> nicht.

Eben, also wieso sollte der Compiler da motzen? :-)

von Jobst Q. (joquis)


Lesenswert?

Ok, ich habs falsch verstanden. Als würdest du es nicht wagen, das so zu 
deklarieren. Zu schnell gelesen.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Die Zeile
1
    someStuff_t *someStuff, st;

hat IMHO nichts Mehrdeutiges oder Missverständliches an sich, solange
man nicht der von Stroustrup in die Welt gesetzte Unsitte verfällt, den
Stern an den Typ- statt an den Variablennamen zu kleben:
1
    someStuff_t* someStuff, st;

Diese Schreibweise erweckt tatsächlich den Eindruck, dass auch st ein
someStuff_t-Zeiger sei.

Da aber der verwirrte Frickler die logisch korrektere von beiden
Schreibweisen verwendet hat, meckern weder der Compiler noch die meisten
Leser mit etwas C/C++-Erfahrung. Wenn einer meckert, dann höchstens
Stroustrup höchstpersönlich, der, um den Unsinn wenigstens etwas zu
kaschieren, vermutlich vorschlagen würde, die Deklaration aufzuteilen:
1
    someStuff_t* someStuff;
2
    someStuff_t st;

PS: Nicht, dass ein falscher Eindruck entsteht: Abgesehen von diesem
Punkt habe ich großen Respekt vor Stroustrup.

von Rolf M. (rmagnus)


Lesenswert?

Das * ist Teil des Typs und nicht Teil des Namen. Deshalb ist es 
Quatsch, es zum Namen zu schreiben. Die "Unsitte" ist schon viel früher 
bei K&R passiert. Stroustrup kann man höchstens vorwerfen, dass er in 
C++ die semantischen Regeln nicht gleich mit bereinigt hat, so dass das 
obige tatsächlich zwei Zeiger definiert. Das hat aber vermutlich 
historische Gründe.

von mec (Gast)


Lesenswert?

Rolf M. schrieb:
> Das * ist Teil des Typs und nicht Teil des Namen. Deshalb ist es
> Quatsch, es zum Namen zu schreiben. Die "Unsitte" ist schon viel früher
> bei K&R passiert. Stroustrup kann man höchstens vorwerfen, dass er in
> C++ die semantischen Regeln nicht gleich mit bereinigt hat, so dass das
> obige tatsächlich zwei Zeiger definiert. Das hat aber vermutlich
> historische Gründe.

So wie ich das Verstanden habe, kommen solche Dinge wie "int *i,ii" aus 
einer Zeit wo noch jedes gesparte Zeichen, sehr teuren Speicher sparte. 
Wurde Sowas eigentlich noch in Lochkarten gestanzt?

von Markus F. (mfro)


Lesenswert?

Yalu X. schrieb:
> Wenn einer meckert, dann höchstens
> Stroustrup höchstpersönlich, der, um den Unsinn wenigstens etwas zu
> kaschieren, vermutlich vorschlagen würde, die Deklaration aufzuteilen

Ich nehme an, daß er den '*' an den Datentyp "geklebt" hat, als er 
gerade die Referenz erfunden hatte.
1
int* &i;      // 1. Referenz auf einen Zeiger
2
int *&i;      // 2. Huh?
3
int * &i;     // 3. so kann man's durchgehen lassen

Einen Zeiger auf eine Referenz gibt's nicht, also steht
1
int& *i;      // Fehler

(zum Glück) nicht zur Debatte. Ich persönlich bevorzuge #3.

von Eric B. (beric)


Lesenswert?

Hm, habe gerade kein C Compiler zum greifen bereit:
1
int*i; // 4. Und so, ganz ohne Leerzeichen?

von Eric B. (beric)


Lesenswert?

Rolf M. schrieb:
> Das * ist Teil des Typs und nicht Teil des Namen.

Eben nicht, sonst gäbe es die ganze Debatte nicht. ;-)

> Die "Unsitte" ist schon viel früher bei K&R passiert.

Da gebe ich dir völlig Recht.

> Stroustrup kann man höchstens vorwerfen, dass er in
> C++ die semantischen Regeln nicht gleich mit bereinigt hat, so dass das
> obige tatsächlich zwei Zeiger definiert. Das hat aber vermutlich
> historische Gründe.

Kompatibilität zur C, halt.

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.