mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Zugriff auf structs


Autor: Mäx (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo ich habe folgendes Struct:

struct telbuch
{
       char* a ;
       int* b ;
}eintrag1;


Wie fülle ich nun b? Zuweisungen wie eintrag1.b = 77; funktionieren 
nicht!

Ich steh total auf dem schlauch. Die Verwendung von structs allgem. 
(also ohne pointer) ist mir bekannt!

bitte helft mir!

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
a und b sind Pointer. Solange Du die Pointer nicht initialisierst, 
zeigen sie irgendwohin.

Du musst also irgendwo und irgendwie den Speicher zur Verfügung stellen, 
auf den diese Pointer zeigen, damit Du mit Deiner Struktur sinnvolles 
anstellen kannst.


Wenn Du das erledigt hast, und Du nun Werte in den Speicher schreiben 
möchtest, auf den die Strukturelemente verweisen, musst Du wie bei einem 
normalen Pointerzugriff die Pointer dereferenzieren. Das geht mit dem 
*-Operator, oder auch, indem Du die Pointer als Array ansprichst - was 
hier aufgrund der fehlenden Information über die Größe des verwendeten 
Speichers problematisch ist.

Also:

  *(eintrag1.b) = 77;

oder

  eintrag1.b[0] = 77;

Autor: Mäx (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
struct telbuch
{
       char* a ;
       int* b ;
};


int main(int argc, char *argv[])
{
    telbuch eintrag1;
    *(eintrag1.b) = 77;
    //printf("askdfj %d    unsigned:%u \r\n",&(eintrag1.b),&(eintrag1.b));   
    
    system("PAUSE");
    return EXIT_SUCCESS;
}


wird kompiliert, schmiert unter windows jedoch ab!!!!

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mäx schrieb:

> wird kompiliert, schmiert unter windows jedoch ab!!!!

logisch.
Wann immer du einen Pointer siehst, musst du dich sofort fragen: Wo 
zeigt er hin?
Ein Pointer ist eine Variable, die eine Speicheradresse enthält. Aber: 
Um einen Wert an dieser Speicheradresse abzulegen, muss es dort auch 
Speicher geben!

Eine Pointervariable selbst kümmert sich nicht um die Bereitstellung des 
Speichers. Sie enthält einfach nur die Adresse des Speichers. Das der 
Pointer auf etwas sinnvolles zeigt, ist dein Bier als Programmierer.

(UNd nein. Mit struct hat das im eigentlichen Sinne gar nichts zu tun. 
Das ist ganz einfach "Arbeiten mit Pointern")

eintrag.b ist bei dir ein Pointer. Er enthält also die Adresse im 
Speicher an der die tatsächlichen Daten zu finden sind. Aber wo ist das? 
Wo hat dieser Pointer einen Speicheradresse zugewiesen bekommen, an der 
der int tatsächlich gespeichert werden kann?

Autor: Mäx (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich verstehe die aussage nicht ganz. Hat mein System keinen Speicher?
die lsg von rufus hat mir nicht geholfen, mein code steht ja im letzen 
beitrag.


wenn ich pointer verwende, könnte ich zb

void foo(int *a);

und foo(&value); nutzen also die allgem. verwendung von pointern ist mir 
ja klar. nur wo ist mein problem? das Strukt soll wie oben beschrieben 
erhalten bleiben und ich will doch nur a und b befüllen bzw später auch 
auslesen

Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Konsolenprogramm?

int main()
{
  telbuch.b = NULL;      //Nullsetzen am Programmanfang, wichtig!!

  telbuch.b = new int;   //Speicherplatz reservieren

  if(telbuch.b)            //falls Zeiger in Ordnung (nicht NULL)
    *(telbuch.b) = 77;     //Speicherplatz mit Wert belegen

// irgendwie damit arbeiten




  delete telbuch.b;       //Speicherplatz wieder freigeben

  return 0;
}

müsste so funktionieren, eventuell noch bei dir anpassen.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mäx schrieb:
> ich verstehe die aussage nicht ganz. Hat mein System keinen Speicher?

Aus Sicht des C Programms nur insofern als es einen Pool von Speicher 
gibt, aus dem sich das C Programm bedienen kann. Das muss jedoch 
geordnet passieren. Du darfst nicht einfach im Speicher zugreifen wie du 
lustig bist.

Insofern hat das System keinen Speicher, ausser dem, den dein C-Programm 
angefordert hat.
Dein konkretes Programm fordert aber keinen Speicher an, ausser dem in 
dem die struct abgelegt wird. Das reicht deinem Programm aber nicht. Du 
willst ja nicht nur die struct (und damit die Pointer) als Elemente im 
Speicher haben, du willst ja auch noch Speicher benutzen können um darin 
einen int abzulegen.
Nur wo ist dieser Speicher? Wo fordert ihn dein C-Programm an?

(Sei froh, dass dir Windows hier auf die Finger klopft. Viel schlimmer 
wäre es, wenn es das nicht täte und dein Schreibversuch im Speicher 
irgendwelche anderen vitalen Daten überschreibt)

Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
bei deinen foo beispiel wurde schon ein Speicherplatz reserviert, und 
zwar durch die Deklaration von "value".
Durch "&value" übergibst du die Adresse der Variable an einen Zeiger, 
der dann auf den Speicherplatz von "value" zeigt.
Bei deinem "telbuch.b" wird aber nicht auf eine schon vorhandene 
Variable gezeigt, also musst du dir Speicher besorgen.

Autor: gerd (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mäx schrieb:
> ich verstehe die aussage nicht ganz. Hat mein System keinen Speicher?

Wollen wir hoffen das es welchen hat... :/

> wenn ich pointer verwende, könnte ich zb
>
> void foo(int *a);
>
> und foo(&value); nutzen also die allgem. verwendung von pointern ist mir
> ja klar.

Anscheinend nicht so ganz. Was würde in deinem o.g. Bsp denn an der 
Adresse von value liegen?


> nur wo ist mein problem?

Lies noch mal den Text von Karl heinz mit Sinn und Verstand. Er hat es 
ziemlich gut auf den Punkt gebracht.

> das Strukt soll wie oben beschrieben
> erhalten bleiben und ich will doch nur a und b befüllen bzw später auch
> auslesen

Der Knackpunkt ist, womit willst du a und b befüllen?
Sinnvoll wäre die Adresse einer Speicherzelle (z.B. Position in einem 
Array), um dann über den Pointer direkt auf die Speicherzelle schreiben 
zu können (oder wie du schreibst "sie zu befüllen").

> die lsg von rufus hat mir nicht geholfen, mein code steht ja im letzen
> beitrag.

Wie gesagt - nochmal lesen und vor allem auch verstehen. ;)

- gerd

Autor: Genmutant (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Falls du C benutzt wird dir Flos Code nicht viel helfen ;)
Hier nochmal für C:
struct telbuch
{
       char* a ;
       int* b ;
};


int main(int argc, char *argv[])
{
    telbuch eintrag1;
    eintrag1.b = malloc(sizeof(int));
    if(eintrag1.b == 0)return EXIT_FAILURE; //Fehler beim Speicheranfordern
    *(eintrag1.b) = 77;
    //printf("askdfj %d    unsigned:%u \r\n",&(eintrag1.b),&(eintrag1.b));   

    return EXIT_SUCCESS;
}

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mäx schrieb:

> erhalten bleiben und ich will doch nur a und b befüllen bzw später auch
> auslesen

Das versteh ich schon.
Nur sind a und b keine Membervariablen in denen du einen char oder einen 
int ablegen kannst!
Das sind Pointer!
int main()
{
  int * ptr;
  int   j;

  ptr = &j;

  *ptr = 5;
}
baut das hier im Speicher auf
    ptr                     j
    +----+                  +----+
    |  o------------------->| 5  |
    +----+                  +----+

Das ganze geht auch mit 'anonymen Speicher'
int main()
{
  int * ptr;

  ptr = malloc( sizeof( int ) );

  *ptr = 8;

  free( ptr );
}
Das baut im Grunde dieselbe Struktur auf, nur dass der Speicher auf den 
ptr zeigt, jetzt keinen Variablennamen mehr hat und erst zur Laufzeit 
des Programms angefordert wird:
    ptr                     
    +----+            
    |  o-----------+
    +----+         |  
                   |
                   |      +----+
                   +----->| 8  |
                          +----+

Aber: Der Wert 8 wird nicht in ptr gespeichert! Er wird dort 
gespeichert, wo ptr hinzeigt.

Wichtig ist: Egal wie und warum, am Ende des Pfeiles muss es ein 
Kästchen geben, in dem ein Wert abgelegt werden kann oder aus dem 
gelesen werden kann. Der Pfeil selbst zeigt nur an, wo das ist. Aber der 
Pfeil muss auf für dein Programm reservierten Speicher zeigen 
(symbolisiert durch das Kästchen). Tut er das nicht, dann geht ein 
Schreibversuch 'in den Wald' und du beschreibst Speicher von dem kein 
Mensch weiß wo sich der im Speicher befindet. Und das darf ein 
Laufzeitsystem/Betriebssystem nach Möglichkeit nicht zulassen.

In deinem Fall hast du mit
    telbuch eintrag1;
dieses hier erzeugt
   eintrag1
   +----------+
   | a:  o---------------------->
   +----------+
   | b:  o-------------------------->
   +----------+
Die Pfeile zeigen irgendwo hin (weil sie ja irgendeinen Wert immer haben 
müssen). Aber wo zeigen sie hin? Am Ende der Pfeile existiert kein 
Kästchen, in dem man einen Wert ablegen könnte.

Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ups da war was, ich vergess immer die Unterschiede >_<

Autor: Genmutant (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und ich hab in meinem Übermut natürlich das
free(eintrag1.b);
vor dem letzten return vergessen.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.